public Expression <Func <object, object> > BuildGenericGetter(FieldInfo fieldInfo) { ValidateField(fieldInfo, null); if (EnableCaching && genericGetterCache.TryGetValue(fieldInfo, out var cachedLambda)) { return((Expression <Func <object, object> >)cachedLambda); } var instanceParameter = Expression.Parameter(typeof(object), "instance"); var invokerExpression = Expression.Field( fieldInfo.IsStatic ? null : ExpressionEx.ConvertIfNeeded(instanceParameter, fieldInfo.DeclaringType), fieldInfo); var body = ExpressionEx.CastTypeSafe(invokerExpression, typeof(object)); var lambda = Expression.Lambda <Func <object, object> >(body, instanceParameter); if (EnableCaching) { genericGetterCache.TryAdd(fieldInfo, lambda); } return(lambda); }
public Expression <GenericPropertyGetter> BuildGenericGetter(PropertyInfo propertyInfo) { var getMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, null, true); if (EnableCaching && genericGetterCache.TryGetValue(propertyInfo, out var cachedLambda)) { return((Expression <GenericPropertyGetter>)cachedLambda); } var instanceParameter = Expression.Parameter(typeof(object), "instance"); var inputParameters = Expression.Parameter(typeof(object[]), "indexers"); var methodCallParameters = propertyInfo.GetIndexParameters() .Select((x, i) => ExpressionEx.ConvertIfNeeded( Expression.ArrayAccess(inputParameters, Expression.Constant(i)), x.ParameterType)); var invokerExpression = Expression.Call( getMethod.IsStatic ? null : ExpressionEx.ConvertIfNeeded(instanceParameter, getMethod.DeclaringType), getMethod, methodCallParameters); var body = ExpressionEx.CastTypeSafe(invokerExpression, typeof(object)); var lambda = Expression.Lambda <GenericPropertyGetter>(body, new[] { instanceParameter, inputParameters }); if (EnableCaching) { genericGetterCache.TryAdd(propertyInfo, lambda); } return(lambda); }
public Expression <GenericStaticInvoker> BuildGeneric(ConstructorInfo ctorInfo) { if (ctorInfo == null) { throw new ArgumentNullException(nameof(ctorInfo)); } if (EnableCaching && genericCache.TryGetValue(ctorInfo, out var cachedLambda)) { return((Expression <GenericStaticInvoker>)cachedLambda); } var inputParameters = Expression.Parameter(typeof(object[]), "parameters"); var methodParameters = ctorInfo.GetParameters(); var methodCallParameters = methodParameters .Select((x, i) => ExpressionEx.ConvertIfNeeded( Expression.ArrayAccess(inputParameters, Expression.Constant(i)), x.ParameterType)); var invokerExpression = Expression.New( ctorInfo, methodCallParameters); var body = ExpressionEx.CastTypeSafe(invokerExpression, typeof(object)); var lambda = Expression.Lambda <GenericStaticInvoker>(body, new[] { inputParameters }); if (EnableCaching) { genericCache.TryAdd(ctorInfo, lambda); } return(lambda); }