I am trying to construct an instance of a generic type and call a method on that instance. Then return the result of the method.
MethodInfo methodInfo = ...;
...
var genericType = typeof(GenericType<>).MakeGenericType(typeof(TOutput));
il.Emit(OpCodes.Newobj, genericType.GetConstructor(Type.EmptyTypes));
il.Emit(OpCodes.Ldobj, methodInfo);
il.Emit(OpCodes.Callvirt, genericeClientHelper.GetMethod("MethodName", new Type[] { typeof(MethodInfo) }));
il.Emit(OpCodes.Ret);
I keep getting a 'System.BadImageFormatException: 'Bad class token.'' exception.
GenericType class looks like this
public class GenericType<T>
{
public T MethodName(MethodInfo methodInfo)
{
...
}
}
You're confusing the boundary between the generated program, and the generating program.
Specifically, your generating program, when run, constructs an instance of an object (a
MethodInfo
instance) and then attempts to generate a program that uses that instance - which it can't because that instance doesn't exist in the generated program, it exists in the memory of the generating program.You have to construct the instance of
MethodInfo
inside your generated program - you have to write the Emit code to generate the IL that constructs theMethodInfo
instance.What you're trying to do makes about as much sense as doing the following:
Thats problem number 1.
Problem number 2 is that you're using the wrong opcode when trying to provide an argument to a method -
Ldobj
doesn't do what you think it does.Instead of using
Ldobj
, you'll have to load the reference by whatever means you fix your generation code to create the internalmethodInfo
. It'll probably be local, so you'll probably end up usingLdloc
or some form thereof.To come full circle, the reason why you're getting the error "Bad class token" is that the value that is supposed to follow
Ldobj
in the compiled IL is supposed to be a class metadata token. What you provided was not a class token, hence the error.As a demonstration, below is a complete program that emulates what you're attempting to do.