public Func <TSource, TTarget> CreateConverter(ModuleBuilder builder) { Initialize(); var typeBuilder = builder.DefineStaticType(); var methodBuilder = typeBuilder.DefineStaticMethod("Map"); methodBuilder.SetReturnType(typeof(TTarget)); methodBuilder.SetParameters(typeof(TSource)); #if NetCore var reflectingTargetType = typeof(TTarget).GetTypeInfo(); var reflectingSourceType = typeof(TSource).GetTypeInfo(); #else var reflectingTargetType = typeof(TTarget); var reflectingSourceType = typeof(TSource); #endif var il = methodBuilder.GetILGenerator(); var context = new CompilationContext(il); if (reflectingSourceType.IsValueType) { context.SetSource(purpose => { if (purpose == LoadPurpose.MemberAccess) { il.Emit(OpCodes.Ldarga_S, 0); } else { il.Emit(OpCodes.Ldarg_0); } }); } else { context.SetSource(purpose => il.Emit(OpCodes.Ldarg_0)); } var targetLocal = il.DeclareLocal(typeof(TTarget)); _creator.Emit(context); il.Emit(OpCodes.Stloc, targetLocal); if (reflectingTargetType.IsValueType) { context.SetTarget( purpose => il.Emit(purpose == LoadPurpose.MemberAccess ? OpCodes.Ldloca_S : OpCodes.Ldloc, targetLocal)); } else { context.SetTarget(purpose => il.Emit(OpCodes.Ldloc, targetLocal)); } EmitMap(context); context.LoadTarget(LoadPurpose.ReturnValue); context.Emit(OpCodes.Ret); #if NetCore return((Func <TSource, TTarget>)typeBuilder.CreateTypeInfo().GetMethod("Map", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(Func <TSource, TTarget>))); #else return((Func <TSource, TTarget>)Delegate.CreateDelegate(typeof(Func <TSource, TTarget>), typeBuilder.CreateType(), "Map")); #endif }
public virtual Delegate CreateDelegate(Type sourceType, Type targetType, ModuleBuilder builder) { var typeBuilder = builder.DefineStaticType(); var methodBuilder = typeBuilder.DefineStaticMethod("Map"); methodBuilder.SetParameters(sourceType, targetType); var il = methodBuilder.GetILGenerator(); var context = new CompilationContext(il); context.SetSource(purpose => il.Emit(OpCodes.Ldarg_0)); context.SetTarget(purpose => il.Emit(OpCodes.Ldarg_1)); Emit(sourceType, targetType, context); context.Emit(OpCodes.Ret); #if NetCore return(typeBuilder.CreateTypeInfo() .GetMethod("Map", BindingFlags.Static | BindingFlags.Public) .CreateDelegate(typeof(Action <,>).MakeGenericType(sourceType, targetType))); #else return(Delegate.CreateDelegate(typeof(Action <,>).MakeGenericType(sourceType, targetType), typeBuilder.CreateType(), "Map")); #endif }
public Action <TSource, TTarget> CreateMapper(ModuleBuilder builder) { Initialize(); if (_customMapper != null) { return(_customMapper); } var typeBuilder = builder.DefineStaticType(); var methodBuilder = typeBuilder.DefineStaticMethod("Map"); methodBuilder.SetReturnType(typeof(void)); methodBuilder.SetParameters(typeof(TSource), typeof(TTarget)); #if NetCore var reflectingTargetType = typeof(TTarget).GetTypeInfo(); var reflectingSourceType = typeof(TSource).GetTypeInfo(); #else var reflectingTargetType = typeof(TTarget); var reflectingSourceType = typeof(TSource); #endif var il = methodBuilder.GetILGenerator(); var context = new CompilationContext(il); if (reflectingSourceType.IsValueType) { context.SetSource(purpose => { if (purpose == LoadPurpose.MemberAccess) { il.Emit(OpCodes.Ldarga_S, 0); } else { il.Emit(OpCodes.Ldarg_0); } }); } else { context.SetSource(purpose => il.Emit(OpCodes.Ldarg_0)); } if (reflectingTargetType.IsValueType) { context.SetTarget(purpose => { if (purpose == LoadPurpose.MemberAccess) { il.Emit(OpCodes.Ldarga_S, 1); } else { il.Emit(OpCodes.Ldarg_1); } }); } else { context.SetTarget(purpose => il.Emit(OpCodes.Ldarg_1)); } EmitMap(context); context.Emit(OpCodes.Ret); #if NetCore return((Action <TSource, TTarget>)typeBuilder.CreateTypeInfo().GetMethod("Map", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(Action <TSource, TTarget>))); #else return((Action <TSource, TTarget>)Delegate.CreateDelegate(typeof(Action <TSource, TTarget>), typeBuilder.CreateType(), "Map")); #endif }