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 Func <TSource, TTarget> CreateConverter(ModuleBuilder builder) { Initialize(); TypeBuilder typeBuilder = builder.DefineStaticType(); MethodBuilder methodBuilder = typeBuilder.DefineStaticMethod("Map"); methodBuilder.SetReturnType(typeof(TTarget)); methodBuilder.SetParameters(typeof(TSource)); ILGenerator il = methodBuilder.GetILGenerator(); var context = new CompilationContext(il); context.SetSource(() => il.Emit(OpCodes.Ldarg_0)); LocalBuilder targetLocal = il.DeclareLocal(typeof(TTarget)); _creator.Emit(context); il.Emit(OpCodes.Stloc, targetLocal); context.SetTarget(() => il.Emit(OpCodes.Ldloc, targetLocal)); if (_customInvokerBuilder != null) { il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldloc, targetLocal); _customInvokerBuilder.Emit(context); } else { foreach (MemberMapper mapper in _memberMappers) { mapper.Emit(context); } } context.LoadTarget(); context.Emit(OpCodes.Ret); return ((Func <TSource, TTarget>) Delegate.CreateDelegate(typeof(Func <TSource, TTarget>), typeBuilder.CreateType(), "Map")); }