using System.Reflection.Emit;
namespace ExplictOperatorTest
public static void Main(string[] args)
var mySourceTypeType = CreateMyType();
var mySourceTypeInstance = Activator.CreateInstance(mySourceTypeType);
MySourceClassDefined test1 = new MySourceClassDefined();
MyTargetClass test2 = (MyTargetClass)test1;
MyTargetClass myTarget1 = (MyTargetClass)mySourceTypeType.GetMethod("ToTargetType").Invoke(mySourceTypeInstance, new object[]{});
MyTargetClass myTarget2 = (MyTargetClass)mySourceTypeType.GetMethod("op_Explicit").Invoke(null, new object[]{mySourceTypeInstance});
var myTarget = (MyTargetClass)mySourceTypeInstance;
private static AssemblyBuilder _assemblyBuilder = null;
private static Type CreateMyType()
TypeBuilder typeBuilder = GetTypeBuilder();
MethodBuilder methodBuilder = typeBuilder.DefineMethod("ToTargetType", MethodAttributes.Public, typeof (MyTargetClass), new Type[]{});
var ilGenerator = methodBuilder.GetILGenerator();
var targetConstructor = typeof (MyTargetClass).GetConstructor(new Type[]{});
var myTargetLocal = ilGenerator.DeclareLocal(typeof (MyTargetClass));
ilGenerator.Emit(OpCodes.Newobj, targetConstructor);
ilGenerator.Emit(OpCodes.Stloc, myTargetLocal);
var setMethod = typeof (MyTargetClass).GetProperty("Test").GetSetMethod();
ilGenerator.Emit(OpCodes.Ldloc, myTargetLocal);
ilGenerator.Emit(OpCodes.Ldstr, "Hello, world");
ilGenerator.EmitCall(OpCodes.Call, setMethod, new Type[]{typeof (string)});
ilGenerator.Emit(OpCodes.Ldloc, myTargetLocal);
ilGenerator.Emit(OpCodes.Ret);
CreateExplicitOp(typeBuilder, methodBuilder.GetBaseDefinition());
return typeBuilder.CreateType();
private static void CreateExplicitOp(TypeBuilder typeBuilder, MethodInfo conversionMethod)
var myType = typeBuilder.AsType();
var method = typeBuilder.DefineMethod("op_Explicit", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Static, typeof (MyTargetClass), new Type[]{myType});
var ilGenerator = method.GetILGenerator();
var emitRecordLocal = ilGenerator.DeclareLocal(typeof (MyTargetClass));
ilGenerator.Emit(OpCodes.Nop);
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.EmitCall(OpCodes.Callvirt, conversionMethod, new Type[]{});
ilGenerator.Emit(OpCodes.Stloc_0);
ilGenerator.Emit(OpCodes.Ldloc_0);
ilGenerator.Emit(OpCodes.Ret);
private static TypeBuilder GetTypeBuilder()
var typeSignature = "MySourceClass";
var assemblyName = new AssemblyName(typeSignature);
_assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, @"c:\temp\");
ModuleBuilder moduleBuilder = _assemblyBuilder.DefineDynamicModule("DynamicViewModel", "dynamic.dll");
TypeBuilder typeBuilder = moduleBuilder.DefineType(typeSignature, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, null);
typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
public class MyTargetClass
public class MySourceClassDefined
public static explicit operator MyTargetClass(MySourceClassDefined myClass)
return myClass.ToTargetType();
public MyTargetClass ToTargetType()
var myTargetClass = new MyTargetClass();
myTargetClass.Test = "Hello, world";