简体   繁体   中英

Reflection.Emit and generic types

I am using Reflection.Emit and I want to create a type that would be the equivalent of the following type defined in C#:

class A
{
    public Tuple<A, int> GetValue(int x)
    {
         return new Tuple<A, int>(this, x);
    }
}

The trick is that I need to use a generic type from BCL that uses my custom type as a generic argument.

I'm messing with the following snippet:

var asmName = new AssemblyName("Test");
var access = AssemblyBuilderAccess.Run;
var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, access);
var module = asm.DefineDynamicModule("Test");

var aType = module.DefineType("A");
var tupleType = typeof(Tuple<,>).MakeGenericType(aType, typeof(int));

var attrs = MethodAttributes.Public;
var method = aType.DefineMethod("GetValue", attrs, tupleType, new [] { typeof(int) });
var gen = method.GetILGenerator();

gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);

// here is the fail:
var ctor = tupleType.GetConstructor(new [] { typeof(int), aType } );
gen.Emit(OpCodes.Newobj, ctor);

The call to GetConstructor fails with the following exception:

NotSupportedException: Specified method is not supported.

So, basically, it won't let me get the constructor of a type that merely references my custom type, and neither can I finalize the type before emitting the body of its method.

Can it really be impossible to get out of this vicious circle?

For some reason, you need to use the static overload of GetConstructor() to do this. In your case, the code could look like this:

var ctor = TypeBuilder.GetConstructor(
    tupleType, typeof(Tuple<,>).GetConstructors().Single());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM