Недопустимый код IL, успешно запущенный в. NET Core 3.1, но не в. NET Framework 4.8 - PullRequest
3 голосов
/ 23 марта 2020

Я делаю ... хм, скажем, эксперимент. У меня есть интерфейс маркера (в нем ничего нет, он только для внедрения зависимостей). Где-то в моем коде я определяю сервис, у которого есть этот интерфейс маркера, и я ищу с помощью отражения определенный c метод в нем - он должен вызываться Execute и возвращать Task. Если я нахожу такой метод, я создаю DynamicMethod и выдаю инструкцию, необходимую для получения метода.
Вот упрощенный код, который требует только метод с этой сигнатурой:

Task Execute(CancellationToken token)

И код для выполнения такого метода:

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>));

Теперь он успешно работал в. NET Core 3.1, я использовал Console App для тестирования.
Однако, когда я пытался запустить его в. NET Framework 4.8 снова в консольном приложении, код, который вызывает executeDelegate (не показан в примере), вызывает исключение:

System.Security.VerificationException: операция может дестабилизировать среду выполнения.

Теперь проблема вроде бы очевидна - интерфейс маркера IExecutable не имеет такого метода, и метод принимает IExecutable в качестве параметра, поэтому для его исправления после загрузки цели инструкция castclass должна быть выпущен, но это работает нормально под. NET Core 3.1 без приведения.

Так что если кто-то знает, почему. NET Core ведет себя так, по любой причине или что-то, пожалуйста, сделайте Поделиться?

Спасибо.

...