Ответ 1
Вот несколько указателей
http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx
Можно ли вставить код IL в метод С#?
Вот несколько указателей
http://www.codeproject.com/KB/dotnet/CLRMethodInjection.aspx
Я только что опубликовал утилиту, которая позволяет автоматически заменять целые тела функций С# на встроенный IL, используя пользовательский атрибут. Как и в случае с аналогичными утилитами, это работает через двустороннюю передачу ILDASM/ILASM, которую можно настроить как этап после сборки. Инструмент также настраивает PDB, чтобы сохранить пошаговые настройки и установку точек останова для отдельных инструкций IL в отладчике. Он отличается от некоторых других встроенных IL-циклов тем, что он (только) заменяет целые функциональные тела, например:
class MyClass
{
[ILFunc(@"
.locals init ([0] int32 i_arg)
ldc.i4.3
ret
")]
int MyFunc(int i_arg)
{
return 3;
}
};
Для методов, критически важных для производительности, я попытался использовать DynamicMethod
чтобы улучшить сгенерированный компилятором IL, но обнаружил, что преимущество теряется из-за накладных расходов на вызов делегата. Встроенный IL дает преимущество настраиваемого IL без этого удара, при условии, что нет никаких настроек времени выполнения, для которых вам действительно нужен DynamicMethod
.
Полный исходный код находится по адресу http://www.glennslayden.com/code/c-sharp/inline-il.
Если inline IL (в том же духе встроенной сборки, поддерживаемой компиляторами C и С++), является тем, что вы ищете, это может быть достигнуто с помощью компиляции с обратной компиляцией.
Майк Столл когда-то писал инструмент для этого, насколько я знаю, он достаточно зрелый:
Кроме этого, вы можете использовать F #, который поддерживает Inline IL.
Необходимый инструмент называется Cecil и является частью проекта Mono.
Вы можете получить дополнительную информацию об этом здесь: http://www.mono-project.com/Cecil
Процитировано на веб-сайте выше:
Cecil - это библиотека, написанная Jb Evain (http://evain.net/blog/) для создания и проверки программ и библиотек в формате ECMA CIL. Он имеет полную поддержку дженериков и поддерживает некоторый формат отладочного символа.
На простом английском языке с помощью Cecil вы можете загружать существующие управляемые сборки, просматривать все содержащиеся в нем типы, изменять их на лету и сохранять обратно на диск измененную сборку.
DynamicMethod - это легкий способ выполнить это во время выполнения.
Компилятор Microsoft С# не поддерживает инъекцию IL во время компиляции, но инструмент для кодового ткачества может сделать это как шаг после компиляции.
Я добавлю свой собственный инструмент в список решений, уже предоставленных здесь: InlineIL.Fody.
При этом используется ткацкий инструмент сборки Fody для изменения сборки во время сборки. Это означает, что все, что вам нужно сделать, это установить пакет NuGet, добавить файл конфигурации в ваш проект, и все готово.
Затем вам предоставляется простой и безопасный для типов API для генерации инструкций IL, который вы можете смешивать с кодом С#. Я считаю, что писать IL таким способом проще, чем писать текст, и это также удобнее, чем ILGenerator
поскольку каждый код операции получает свой собственный метод только с соответствующими перегрузками.
Вот пример с using static InlineIL.IL.Emit;
:
public static void ZeroInit<T>(ref T value)
where T : struct
{
Ldarg(nameof(value));
Ldc_I4_0();
Sizeof(typeof(T));
Unaligned(1);
Initblk();
}
Это показывает, как получить доступ к инструкции initblk
которую С# в настоящее время не предоставляет.