Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to emit explicit interface implementation using reflection.emit?
    text
    copied!<p>Observe the following simple source code:</p> <pre><code>using System; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; namespace A { public static class Program { private const MethodAttributes ExplicitImplementation = MethodAttributes.Private | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot; private const MethodAttributes ImplicitImplementation = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig; private static Type EmitMyIntfType(ModuleBuilder moduleBuilder) { var typeBuilder = moduleBuilder.DefineType("IMyInterface", TypeAttributes.NotPublic | TypeAttributes.Interface | TypeAttributes.Abstract); typeBuilder.DefineMethod("MyMethod", MethodAttributes.Assembly | MethodAttributes.Abstract | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot, typeof(void), new[] { typeof(int) }); return typeBuilder.CreateType(); } public static void Main() { var assemblyName = new AssemblyName("DynamicTypesAssembly"); var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); var moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll", true); var myIntfType = EmitMyIntfType(moduleBuilder); var typeBuilder = moduleBuilder.DefineType("MyType", TypeAttributes.Public | TypeAttributes.BeforeFieldInit | TypeAttributes.Serializable | TypeAttributes.Sealed, typeof(object), new[] { myIntfType }); //var myMethodImpl = typeBuilder.DefineMethod("IMyInterface.MyMethod", ExplicitImplementation, // null, new[] { typeof(int) }); var myMethodImpl = typeBuilder.DefineMethod("MyMethod", ImplicitImplementation, null, new[] { typeof(int) }); var ilGenerator = myMethodImpl.GetILGenerator(); ilGenerator.Emit(OpCodes.Ret); var type = typeBuilder.CreateType(); assemblyBuilder.Save("A.dll"); } } } </code></pre> <p>Below is the equivalent C# code obtained by decompiling the A.dll assembly using the Reflector:</p> <pre><code>internal interface IMyInterface { void MyMethod(int); } [Serializable] public sealed class MyType : IMyInterface { public override void MyMethod(int) { } } </code></pre> <p>Now what if I wish the <code>MyType</code> type implement the <code>IMyInterface</code> interface explicitly? So I take these lines:</p> <pre><code>//var myMethodImpl = typeBuilder.DefineMethod("IMyInterface.MyMethod", ExplicitImplementation, // null, new[] { typeof(int) }); var myMethodImpl = typeBuilder.DefineMethod("MyMethod", ImplicitImplementation, null, new[] { typeof(int) }); </code></pre> <p>and switch the comments to yield this code:</p> <pre><code>var myMethodImpl = typeBuilder.DefineMethod("IMyInterface.MyMethod", ExplicitImplementation, null, new[] { typeof(int) }); // var myMethodImpl = typeBuilder.DefineMethod("MyMethod", ImplicitImplementation, // null, new[] { typeof(int) }); </code></pre> <p>But now, the application fails to create the dynamic type. This line:</p> <pre><code>var type = typeBuilder.CreateType(); </code></pre> <p>throws the following exception:</p> <pre><code>System.TypeLoadException was unhandled Message="Method 'MyMethod' in type 'MyType' from assembly 'DynamicTypesAssembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation." Source="mscorlib" TypeName="MyType" StackTrace: at System.Reflection.Emit.TypeBuilder._TermCreateClass(Int32 handle, Module module) at System.Reflection.Emit.TypeBuilder.TermCreateClass(Int32 handle, Module module) at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.TypeBuilder.CreateType() at A.Program.Main() in C:\Home\work\A\Program.cs:line 45 InnerException: </code></pre> <p>Can anyone show me what is wrong with my code?</p> <p>Thanks.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload