Invalid IL code running successfully in .NET Core 3.1, but fails in .NET Framework 4.8

Viewed 179

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.

0 Answers
Related