I am doing a... hm lets say an experiment. I have a marker interface (it doesn't have anything in it, it is just for dependency injection). I resolve somewhere in my code a service that has this marker interface and I search via reflection for a specific method in it - it has to be called Execute and to return a Task. If I find such a method I create a DynamicMethod and emit the instruction needed to get the method.
Here is a simplified code that only wants a method with this signature:
Task Execute(CancellationToken token)
And the code for executing such method is:
var dm = new DynamicMethod("SomeDynamicMethod", typeof(Task), new[] { typeof(IExecutable), typeof(CancellationToken) });
var il = dm.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
var method = typeof(Foo).GetMethod("Execute", new[] { typeof(CancellationToken) });
il.Emit(OpCodes.Callvirt, method);
il.Emit(OpCodes.Ret);
var executeDelegate = (Func<IExecutable, CancellationToken, Task>)dm.CreateDelegate(typeof(Func<IExecutable, CancellationToken, Task>));
Now this was running successfully under .NET Core 3.1, I used Console App for testing.
However when I tried to run it under .NET Framework 4.8 again in Console App, the code that calls the executeDelegate (not shown in the example) throws an exception:
System.Security.VerificationException: Operation could destabilize the runtime.
Now the problem is kinda obvious - IExecutable marker interface doesn't have such method and the method accepts IExecutable as a parameter, so to fix it after loading the target a castclass instruction should be emitted,
but this is running fine under .NET Core 3.1 without a cast.
So if anyone knows why .NET Core behaves like that, any reason or something, please do share?
Thanks.