public LambdaExpression BuildStaticGetter(PropertyInfo propertyInfo, Type valueType = null) { var getMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, true, true); CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(propertyInfo, null, valueType, null); if (getterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } var delegateType = GenericTypeExtensions.GetFuncGenericType(valueType ?? propertyInfo.PropertyType); var lambda = Expression.Lambda( delegateType, GetCastedValueExpression(Expression.Call(null, getMethod), valueType)); if (EnableCaching) { getterCache.TryAdd(cacheKey, lambda); } return(lambda); }
public LambdaExpression BuildStaticSetter(PropertyInfo propertyInfo, Type valueType = null) { var setMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, true, false); valueType = valueType ?? propertyInfo.PropertyType; CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(propertyInfo, null, valueType, null); if (setterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } var value = Expression.Parameter(valueType, "value"); var delegateType = GenericTypeExtensions.GetActionGenericType(valueType); var lambda = Expression.Lambda( delegateType, Expression.Call(null, setMethod, GetCastedValueExpression(value, propertyInfo.PropertyType)), value); if (EnableCaching) { getterCache.TryAdd(cacheKey, lambda); } return(lambda); }
public Delegate BuildStaticGetter(FieldInfo fieldInfo, Type valueType = null) { CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(fieldInfo, null, valueType); if (getterCache.TryGetValue(cacheKey, out var cachedDelegate)) { return(cachedDelegate); } } Delegate _delegate; if (!fieldInfo.IsInitOnly) { _delegate = builder.BuildStaticGetter(fieldInfo, valueType).Compile(); } else #if NET45 { _delegate = Emit.FieldAccessorMethodEmitter.GetFieldSetter(fieldInfo, GenericTypeExtensions.GetActionGenericType(valueType ?? fieldInfo.FieldType)); } #else { throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set."); } #endif if (EnableCaching) { getterCache.TryAdd(cacheKey, _delegate); } return(_delegate); }
public LambdaExpression BuildStaticGetter(FieldInfo fieldInfo, Type valueType = null) { ValidateField(fieldInfo, true); CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(fieldInfo, null, valueType); if (getterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } var delegateType = GenericTypeExtensions.GetFuncGenericType(valueType ?? fieldInfo.FieldType); var lambda = Expression.Lambda( delegateType, GetCastedValueExpression(Expression.Field(null, fieldInfo), valueType)); if (EnableCaching) { getterCache.TryAdd(cacheKey, lambda); } return(lambda); }
public LambdaExpression BuildInstanceGetter(FieldInfo fieldInfo, Type instanceType = null, Type valueType = null) { ValidateField(fieldInfo, false); CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(fieldInfo, instanceType, valueType); if (getterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } instanceType = instanceType ?? fieldInfo.DeclaringType; valueType = valueType ?? fieldInfo.FieldType; var instance = Expression.Parameter(instanceType, "instance"); var castedInstance = GetCastedInstanceExpression(instance, fieldInfo); var delegateType = GenericTypeExtensions.GetFuncGenericType(instanceType, valueType); var lambda = Expression.Lambda( delegateType, GetCastedValueExpression(Expression.Field(castedInstance, fieldInfo), valueType), instance); if (EnableCaching) { getterCache.TryAdd(cacheKey, lambda); } return(lambda); }
public void IsConcreteInstanceOfGenericTypeDefinition_TypesDoNotMatch_False() { var aType = typeof(CommandError).GetTypeInfo(); var generic = typeof(CommandResult <>); var result = GenericTypeExtensions.IsConcreteInstanceOfGenericTypeDefinition(aType, generic); Assert.False(result); }
public void GetConcreteInterfaceImplementationForGenericInterface_TypesDoNotMatch_Null() { var aType = typeof(CommandError).GetTypeInfo(); var generic = typeof(ICustomCommandHandler <,>); var result = GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic); Assert.Null(result); }
public void GetConcreteInterfaceImplementationForGenericInterface_TypesMatch_True() { var aType = typeof(TestCommandHandler).GetTypeInfo(); var generic = typeof(ICustomCommandHandler <,>); var result = GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic); Assert.Equal(typeof(ICustomCommandHandler <TestCommand, CommandResult <CommandError> >), result); }
public void GetConcreteInterfaceImplementationForGenericInterface_InterfaceNotGeneric_Throws() { var aType = typeof(CommandError).GetTypeInfo(); var generic = typeof(IFormattable); var exception = Assert.Throws <ArgumentException>(() => GenericTypeExtensions.GetConcreteInterfaceImplementationForGenericInterface(aType, generic)); AssertCorrectArgumentException(exception); }
public LambdaExpression BuildInstanceSetter(FieldInfo fieldInfo, Type instanceType = null, Type valueType = null) { ValidateField(fieldInfo, false); CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(fieldInfo, instanceType, valueType); if (setterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } instanceType = instanceType ?? fieldInfo.DeclaringType; valueType = valueType ?? fieldInfo.FieldType; var instance = Expression.Parameter(instanceType, "instance"); var value = Expression.Parameter(valueType, "value"); var expressionParameters = new[] { instance, value }; var castedInstance = GetCastedInstanceExpression(instance, fieldInfo); var delegateType = GenericTypeExtensions.GetActionGenericType(instanceType, valueType); LambdaExpression lambda; if (!fieldInfo.IsInitOnly) { lambda = Expression.Lambda( delegateType, Expression.Assign( Expression.Field(castedInstance, fieldInfo), GetCastedValueExpression(value, fieldInfo.FieldType)), expressionParameters); } else { #if !NETSTANDARD2_0 var m = Reflection.Emit.FieldAccessorMethodEmitter.GetFieldSetterMethod(fieldInfo, delegateType); lambda = Expression.Lambda( delegateType, Expression.Call(m, castedInstance, GetCastedValueExpression(value, fieldInfo.FieldType)), expressionParameters); #else throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set."); #endif } if (EnableCaching) { setterCache.TryAdd(cacheKey, lambda); } return(lambda); }
public static Delegate GetFieldGetter(FieldInfo field, Type delegateType = null) { var method = GetFieldSetterMethod(field, delegateType); if (delegateType == null) { delegateType = GenericTypeExtensions.GetFuncGenericType((field.IsStatic ? new[] { field.DeclaringType } : new Type[] { }).Concat(new[] { field.FieldType })); } return(method.CreateDelegate(delegateType)); }
public LambdaExpression BuildInstanceSetter(PropertyInfo propertyInfo, Type instanceType = null, Type valueType = null, IEnumerable <Type> indexerTypes = null) { var setMethod = ValidatePropertyAndGetAccessorMethod(propertyInfo, false, false); CacheKey cacheKey = null; if (EnableCaching) { cacheKey = new CacheKey(propertyInfo, instanceType, valueType, indexerTypes); if (setterCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } instanceType = instanceType ?? propertyInfo.DeclaringType; valueType = valueType ?? propertyInfo.PropertyType; var instance = Expression.Parameter(instanceType, "instance"); var value = Expression.Parameter(valueType, "value"); var indexedParameters = propertyInfo.GetIndexParameters(); var indexedParametersExpressions = indexerTypes == null? indexedParameters.Select((x, i) => Expression.Parameter(x.ParameterType, "itemIndexer" + i)).ToList() : indexedParameters.Zip(indexerTypes, (p, i) => new { p, i }).Select((x, i) => Expression.Parameter(x.i ?? x.p.ParameterType, "itemIndexer" + i)).ToList(); var expressionParameters = new[] { instance }.Concat(indexedParametersExpressions).Concat(new[] { value }); var castedInstance = GetCastedInstanceExpression(instance, propertyInfo); var methodCallparameters = (indexerTypes == null ? indexedParametersExpressions : indexedParametersExpressions .Zip(indexedParameters, (p, i) => GetCastedValueExpression(p, i.ParameterType))) .Concat(new[] { GetCastedValueExpression(value, propertyInfo.PropertyType) }); var delegateType = GenericTypeExtensions.GetActionGenericType(new Type[] { instanceType }.Concat(expressionParameters.Skip(1).Select(x => x.Type))); var lambda = Expression.Lambda( delegateType, Expression.Call(castedInstance, setMethod, methodCallparameters), expressionParameters); if (EnableCaching) { setterCache.TryAdd(cacheKey, lambda); } return(lambda); }
private LambdaExpression BuildFromTypes(ConstructorInfo ctorInfo, Type instanceType, IEnumerable <Type> parameterTypes, Type delegateType) { CacheKey cacheKey = null; if (EnableCaching && delegateType == null) { cacheKey = new CacheKey(ctorInfo, instanceType, parameterTypes); if (cache.TryGetValue(cacheKey, out var lambda)) { return(lambda); } } var effectiveInstanceType = instanceType ?? ctorInfo.DeclaringType; var constructorParameters = ctorInfo.GetParameters() .ZipOutter(parameterTypes ?? Enumerable.Empty <Type>(), (cp, p) => new { MethodType = cp.ParameterType, Name = cp.Name, InputParameter = Expression.Parameter(p ?? cp.ParameterType, cp.Name), }) .Select(x => new { x.InputParameter, MethodCallParameter = x.MethodType == x.InputParameter.Type ? (Expression)x.InputParameter : ExpressionEx.ConvertIfNeeded(x.InputParameter, x.MethodType) }) .ToList(); var effectiveDelegateType = delegateType ?? GenericTypeExtensions.GetFuncGenericType(constructorParameters.Select(x => x.InputParameter.Type).Concat(new[] { effectiveInstanceType })); var invokerExpression = (Expression)Expression.New(ctorInfo, constructorParameters.Select(x => x.MethodCallParameter)); if (effectiveInstanceType != ctorInfo.DeclaringType) { invokerExpression = Expression.Convert(invokerExpression, effectiveInstanceType); } var l = Expression.Lambda(effectiveDelegateType, invokerExpression, constructorParameters.Select(x => x.InputParameter).ToArray()); if (EnableCaching && delegateType == null) { cache.TryAdd(cacheKey, l); } return(l); }
private LambdaExpression BuildInvokerExpressionFromTypes(MethodInfo methodInfo, Type instanceType, IEnumerable <Type> parameterTypes, Type returnType, Type delegateType) { if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } CacheKey cacheKey = null; if (EnableCaching && delegateType != null) { cacheKey = new CacheKey(methodInfo, instanceType, returnType, parameterTypes); if (byTypesCache.TryGetValue(cacheKey, out var cachedLambda)) { return(cachedLambda); } } returnType = returnType ?? methodInfo.ReturnType; instanceType = methodInfo.IsStatic ? null : instanceType ?? methodInfo.DeclaringType; var methodParameters = (methodInfo.IsStatic ? Enumerable.Empty <MethodParameter>() : new[] { new MethodParameter { InputParameter = Expression.Parameter(instanceType, "instance"), MethodType = methodInfo.DeclaringType } }) .Concat(methodInfo.GetParameters().ZipOutter(parameterTypes ?? Enumerable.Empty <Type>(), (mp, pt) => new MethodParameter { InputParameter = Expression.Parameter(pt ?? mp.ParameterType, mp.Name), MethodType = mp.ParameterType })) .Select(x => new { x.InputParameter, MethodCallParameter = x.MethodType == x.InputParameter.Type ? (Expression)x.InputParameter : ExpressionEx.ConvertIfNeeded(x.InputParameter, x.MethodType) }) .ToList(); var isAction = methodInfo.ReturnType == typeof(void) && (returnType == null || returnType == typeof(void)); var effectiveDelegateType = delegateType ?? (isAction ? GenericTypeExtensions.GetActionGenericType(methodParameters.Select(x => x.MethodCallParameter.Type)) : GenericTypeExtensions.GetFuncGenericType(methodParameters.Select(x => x.MethodCallParameter.Type).Concat(new[] { returnType }).ToArray())); var invokerExpression = Expression.Call( methodInfo.IsStatic ? null : methodParameters.Select(x => x.MethodCallParameter).First(), methodInfo, methodParameters.Select(x => x.MethodCallParameter).Skip(methodInfo.IsStatic ? 0 : 1)); var body = methodInfo.ReturnType == typeof(void) ? (!isAction ? (Expression)Expression.Block(typeof(object), invokerExpression, Expression.Constant(null)) : invokerExpression) : Expression.Convert(invokerExpression, returnType); var lambda = Expression.Lambda(effectiveDelegateType, body, methodParameters.Select(x => x.InputParameter)); if (EnableCaching && delegateType != null) { byTypesCache.TryAdd(cacheKey, lambda); } return(lambda); }
public Expression <Action <object, object> > BuildGenericSetter(FieldInfo fieldInfo) { ValidateField(fieldInfo, null); if (EnableCaching && genericSetterCache.TryGetValue(fieldInfo, out var cachedLambda)) { return((Expression <Action <object, object> >)cachedLambda); } var instanceParameter = Expression.Parameter(typeof(object), "instance"); var value = Expression.Parameter(typeof(object), "value"); var castedInstance = ExpressionEx.ConvertIfNeeded(instanceParameter, fieldInfo.DeclaringType); Expression <Action <object, object> > lambda; if (!fieldInfo.IsInitOnly) { lambda = Expression.Lambda <Action <object, object> >( Expression.Assign( Expression.Field(fieldInfo.IsStatic ? null : castedInstance, fieldInfo), GetCastedValueExpression(value, fieldInfo.FieldType)), instanceParameter, value); } else { #if !NETSTANDARD2_0 var m = Reflection.Emit.FieldAccessorMethodEmitter.GetFieldSetterMethod(fieldInfo, GenericTypeExtensions.GetActionGenericType(fieldInfo.DeclaringType, fieldInfo.FieldType)); lambda = Expression.Lambda <Action <object, object> >( Expression.Call(m, castedInstance, GetCastedValueExpression(value, fieldInfo.FieldType)), instanceParameter, value); #else throw new InvalidOperationException($"Field {fieldInfo.Name} is InitOnly and cannot be set."); #endif } if (EnableCaching) { genericGetterCache.TryAdd(fieldInfo, lambda); } return(lambda); }