public static Type GetOrAddCapturedArgumentsType(Expression[] expressions) { var length = expressions.Length; var types = new Type[length]; var foundType = CapturedArgumentTypes.GetOrDefault(length); if (foundType != null) { if (length <= 0) { return(foundType); } for (var i = 0; i < length; i++) { types[i] = expressions[i].Type; } return(foundType.MakeGenericType(types)); } var fields = new FieldInfo[length]; var typeBuilder = ModuleBuilder.Value.DefineType("Stashbox.Dynamic.DT" + Interlocked.Increment(ref typeCounter), TypeAttributes.Public); var typeParamNames = new string[length]; for (var i = 0; i < length; i++) { typeParamNames[i] = "T" + i; } var typeParams = typeBuilder.DefineGenericParameters(typeParamNames); #if NETSTANDARD var genericTypes = new Type[length]; #endif for (var i = 0; i < length; i++) { types[i] = expressions[i].Type; #if NETSTANDARD var genericType = typeParams[i].AsType(); genericTypes[i] = genericType; fields[i] = typeBuilder.DefineField("F" + i, genericType, FieldAttributes.Public); #else fields[i] = typeBuilder.DefineField("F" + i, typeParams[i], FieldAttributes.Public); #endif } #if NETSTANDARD var type = typeBuilder.CreateTypeInfo().AsType(); #else var type = typeBuilder.CreateType(); #endif Swap.SwapValue(ref CapturedArgumentTypes, (t1, t2, t3, t4, t) => t.AddOrUpdate(t1, t2), length, type, Constants.DelegatePlaceholder, Constants.DelegatePlaceholder); return(type.MakeGenericType(types)); }
public static Type GetOrAddTargetType(Type[] types) { var length = types.Length; var foundType = TargetTypes.GetOrDefault(length); if (foundType != null) { return(foundType.MakeGenericType(types)); } var fields = new FieldInfo[length]; var typeBuilder = ModuleBuilder.Value.DefineType("Stashbox.Dynamic.DT" + Interlocked.Increment(ref typeCounter), TypeAttributes.Public); if (length > 0) { var typeParamNames = new string[length]; for (var i = 0; i < length; i++) { typeParamNames[i] = "T" + i; } var typeParams = typeBuilder.DefineGenericParameters(typeParamNames); #if NETSTANDARD var genericTypes = new Type[length]; #endif for (var i = 0; i < length; i++) { #if NETSTANDARD var genericType = typeParams[i].AsType(); genericTypes[i] = genericType; fields[i] = typeBuilder.DefineField("F" + i, genericType, FieldAttributes.Public); #else fields[i] = typeBuilder.DefineField("F" + i, typeParams[i], FieldAttributes.Public); #endif } #if NETSTANDARD var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, genericTypes); #else var constructor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, typeParams); #endif var generator = constructor.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Call, Constants.ObjectConstructor); for (var i = 0; i < length; i++) { generator.Emit(OpCodes.Ldarg_0); generator.LoadParameter(i + 1); generator.Emit(OpCodes.Stfld, fields[i]); } generator.Emit(OpCodes.Ret); } #if NETSTANDARD var type = typeBuilder.CreateTypeInfo().AsType(); #else var type = typeBuilder.CreateType(); #endif Swap.SwapValue(ref TargetTypes, t => t.AddOrUpdate(length, type)); return(type.MakeGenericType(types)); }