Search code examples
c#reflectionreflection.emittypebuilder

Emit explicit interface implementation of a property


Goals

So what I want to do, is creating a type at runtime with the TypeBuilder class. The interface of from which I want the runtime type to implement looks like the following.

public interface ITest
{
    int TestProperty { get; }
}

The type which should be generated should look like the following:

internal class Test : ITest
{
    int ITest.TestProperty { get => 0; }
}

The explicit implementation of the interface isn't really necessary, but that is what I found the most resources on.


Now to the actual code

var assemblyName = new AssemblyName("AssemblyTest");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var module = assemblyBuilder.DefineDynamicModule(assemblyName.Name + ".dll");

var typeBuilder = module.DefineType("TestType", TypeAttributes.NotPublic | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Class, null, new[] { typeof(ITest) });

var prop = typeBuilder.DefineProperty("ITest.TestProperty", PropertyAttributes.HasDefault, typeof(int), null);

var propGet = typeBuilder.DefineMethod("ITest.get_TestProperty", MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final);

var propertyGetIL = propGet.GetILGenerator();

propertyGetIL.Emit(OpCodes.Ldc_I4_0);
propertyGetIL.Emit(OpCodes.Ret);

prop.SetGetMethod(propGet);

typeBuilder.DefineMethodOverride(propGet, typeof(ITest).GetProperty("TestProperty").GetGetMethod());

var type = typeBuilder.CreateType();

Just as a short explanation of the code.

  1. Creation of the DynamicAssembly/Module/Class
  2. Create the Backing Field and the Property itself
  3. Create the content of the Get method for the property
  4. Mark the property as the implementation of the interface
  5. Create the new type

However the CreateType method throws the following at me:

Signature of the body and declaration in a method implementation do not match. Type: 'TestType'. Assembly: 'AssemblyTest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.'

I am really not sure how I would implement the property and what the cause of this is.


Solution

  • You are missing the return type when you define the get method. You need to specify it using a different overload of DefineMethod:

    var propGet = typeBuilder.DefineMethod("ITest.get_TestProperty", 
      MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.NewSlot | 
      MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final,
      typeof(int), // <--- return type
      Type.EmptyTypes // <-- parameter types (indexers)
    );