I am trying to dynamically build a type with a method that calls into an external delegate by using System.Reflection.Emit. However when I try to call this method, my program crashes with the exception in the title at the method call. Here's my code so far:
private static void TestMethodReal() => Console.Out.WriteLine("Inside TestMethod");
// In Main()
var method = typeof(Program).GetMethod(nameof(TestMethodReal), BindingFlags.Static | BindingFlags.NonPublic)!;
var builder = MyTypeBuilder.GetTypeBuilder("TestType");
var testMethod = builder.DefineMethod("TestMethod", MethodAttributes.Public, typeof(void), Type.EmptyTypes);
var generator = testMethod.GetILGenerator();
generator.EmitCall(OpCodes.Callvirt, method, null);
generator.Emit(OpCodes.Ret);
dynamic inst = Activator.CreateInstance(builder.CreateType()!)!;
inst.TestMethod(); // <--- Exception is thrown here
The MyTypeBuilder class and GetTypeBuilder method is from this answer, slightly modified to accept a parameter for the type's name.
This program is supposed to create a new dynamic class with a method called TestMethod that calls the actual TestMethodReal method, instantiate the class, and call the method.
What am I missing?
BindingFlags.Static | BindingFlags.NonPublic)!;. What is that!for?. And again in the line just before your errorActivator.CreateInstance(builder.CreateType()!)!;GetMethodreturns a nullableMethodInfo?type (note the '?' at the end). The!basically ensures that the return value is not null, otherwise my IDE will complain about it and draw an ugly yellow squiggly line underneath it. Same withCreateTypeandCreateInstance, returning nullableType?andobject?types respectively.generator.EmitCall(OpCodes.Call, method, Types.EmptyTypes)- you don't need the runtime to resolveTestMethodRealfor you since you already have an exact reference to it viamethod:)AppDomain.DefineDynamicAssemblyused in linked answer is .NET Framework only.GetTypeBuildermethod.