<PackageReference Include="Newtonsoft.Json" Version="6.0.2" />

ExpressionReflectionDelegateFactory

using System; using System.Linq.Expressions; using System.Reflection; namespace Newtonsoft.Json.Utilities { internal class ExpressionReflectionDelegateFactory : ReflectionDelegateFactory { private static readonly ExpressionReflectionDelegateFactory _instance = new ExpressionReflectionDelegateFactory(); internal static ReflectionDelegateFactory Instance => _instance; public override MethodCall<T, object> CreateMethodCall<T>(MethodBase method) { ValidationUtils.ArgumentNotNull(method, "method"); Type typeFromHandle = typeof(object); ParameterExpression parameterExpression = Expression.Parameter(typeFromHandle, "target"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object[]), "args"); ParameterInfo[] parameters = method.GetParameters(); Expression[] array = new Expression[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Expression index = Expression.Constant(i); Expression expression = Expression.ArrayIndex(parameterExpression2, index); expression = (array[i] = EnsureCastExpression(expression, parameters[i].ParameterType)); } Expression expression2; if (method.IsConstructor) expression2 = Expression.New((ConstructorInfo)method, array); else if (method.IsStatic) { expression2 = Expression.Call((MethodInfo)method, array); } else { Expression instance = EnsureCastExpression(parameterExpression, method.DeclaringType); expression2 = Expression.Call(instance, (MethodInfo)method, array); } if (method is MethodInfo) { MethodInfo methodInfo = (MethodInfo)method; expression2 = ((!(methodInfo.ReturnType != typeof(void))) ? Expression.Block(expression2, Expression.Constant(null)) : EnsureCastExpression(expression2, typeFromHandle)); } else expression2 = EnsureCastExpression(expression2, typeFromHandle); LambdaExpression lambdaExpression = Expression.Lambda(typeof(MethodCall<T, object>), expression2, parameterExpression, parameterExpression2); return (MethodCall<T, object>)lambdaExpression.Compile(); } public override Func<T> CreateDefaultConstructor<T>(Type type) { ValidationUtils.ArgumentNotNull(type, "type"); if (!type.IsAbstract()) try { Type typeFromHandle = typeof(T); Expression expression = Expression.New(type); expression = EnsureCastExpression(expression, typeFromHandle); LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func<T>), expression); return (Func<T>)lambdaExpression.Compile(); } catch { return () => (T)Activator.CreateInstance(type); } return () => (T)Activator.CreateInstance(type); } public override Func<T, object> CreateGet<T>(PropertyInfo propertyInfo) { ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); Type typeFromHandle = typeof(T); Type typeFromHandle2 = typeof(object); ParameterExpression parameterExpression = Expression.Parameter(typeFromHandle, "instance"); MethodInfo getMethod = propertyInfo.GetGetMethod(true); Expression expression; if (getMethod.IsStatic) expression = Expression.MakeMemberAccess(null, propertyInfo); else { Expression expression2 = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType); expression = Expression.MakeMemberAccess(expression2, propertyInfo); } expression = EnsureCastExpression(expression, typeFromHandle2); LambdaExpression lambdaExpression = Expression.Lambda(typeof(Func<T, object>), expression, parameterExpression); return (Func<T, object>)lambdaExpression.Compile(); } public override Func<T, object> CreateGet<T>(FieldInfo fieldInfo) { ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "source"); Expression expression; if (fieldInfo.IsStatic) expression = Expression.Field(null, fieldInfo); else { Expression expression2 = EnsureCastExpression(parameterExpression, fieldInfo.DeclaringType); expression = Expression.Field(expression2, fieldInfo); } expression = EnsureCastExpression(expression, typeof(object)); return Expression.Lambda<Func<T, object>>(expression, new ParameterExpression[1] { parameterExpression }).Compile(); } public override Action<T, object> CreateSet<T>(FieldInfo fieldInfo) { ValidationUtils.ArgumentNotNull(fieldInfo, "fieldInfo"); if (fieldInfo.DeclaringType.IsValueType() || fieldInfo.IsInitOnly) return LateBoundReflectionDelegateFactory.Instance.CreateSet<T>(fieldInfo); ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "source"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object), "value"); Expression expression; if (fieldInfo.IsStatic) expression = Expression.Field(null, fieldInfo); else { Expression expression2 = EnsureCastExpression(parameterExpression, fieldInfo.DeclaringType); expression = Expression.Field(expression2, fieldInfo); } Expression right = EnsureCastExpression(parameterExpression2, expression.Type); BinaryExpression body = Expression.Assign(expression, right); LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action<T, object>), body, parameterExpression, parameterExpression2); return (Action<T, object>)lambdaExpression.Compile(); } public override Action<T, object> CreateSet<T>(PropertyInfo propertyInfo) { ValidationUtils.ArgumentNotNull(propertyInfo, "propertyInfo"); if (propertyInfo.DeclaringType.IsValueType()) return LateBoundReflectionDelegateFactory.Instance.CreateSet<T>(propertyInfo); Type typeFromHandle = typeof(T); Type typeFromHandle2 = typeof(object); ParameterExpression parameterExpression = Expression.Parameter(typeFromHandle, "instance"); ParameterExpression parameterExpression2 = Expression.Parameter(typeFromHandle2, "value"); Expression expression = EnsureCastExpression(parameterExpression2, propertyInfo.PropertyType); MethodInfo setMethod = propertyInfo.GetSetMethod(true); Expression body; if (setMethod.IsStatic) body = Expression.Call(setMethod, expression); else { Expression instance = EnsureCastExpression(parameterExpression, propertyInfo.DeclaringType); body = Expression.Call(instance, setMethod, expression); } LambdaExpression lambdaExpression = Expression.Lambda(typeof(Action<T, object>), body, parameterExpression, parameterExpression2); return (Action<T, object>)lambdaExpression.Compile(); } private Expression EnsureCastExpression(Expression expression, Type targetType) { Type type = expression.Type; if (type == targetType || (!type.IsValueType() && targetType.IsAssignableFrom(type))) return expression; return Expression.Convert(expression, targetType); } } }