Легкая генерация кода (LCG) мертва? - PullRequest
6 голосов
/ 09 июня 2010

В средах .NET 2.0-3.5 LCG (он же класс DynamicMethod) был достойным способом испускать легкие методы во время выполнения, когда для их поддержки не требовалась структура классов.

В .NET 4.0,Деревья выражений теперь поддерживают операторы и блоки и, как таковые, предоставляют достаточные функциональные возможности для создания практически любой функциональности, которая может потребоваться от такого метода, и могут быть созданы гораздо проще и безопаснее, чем непосредственное использование кодов операций CIL.(Это утверждение основано на сегодняшнем эксперименте по преобразованию некоторых из наших самых сложных кодов LCG для использования вместо них построения и компиляции дерева выражений.)

Так есть ли причины, по которым можно было бы использовать LCG в любом новом коде?Есть ли что-нибудь, что могут сделать деревья выражения?Или теперь это «мертвый» функционал?

Ответы [ 4 ]

3 голосов
/ 13 апреля 2011

Нет смысла создавать CIL напрямую без каких-либо промежуточных шагов.Но совершенно нормально использовать ваши собственные промежуточные языки, которые нацелены на IL в конце.Деревья выражений и т. Д. Не достаточны - это всего лишь один язык, тогда как при реализации DSL вам потребуется много разных семантик.

Вы можете легко генерировать небезопасный код (с большим количеством ldftns и т. П.), Вы можете генерировать хвостовые вызовы (не уверен, если это возможно с выражениями), не виртуальные вызовы виртуальных методов, вы можете эффективно создавать автоматы больших состоянийс метками, переходами и т. д. Деревья выражений настолько ограничены, что я просто не могу понять, как их можно сравнить с необработанным CIL.

0 голосов
/ 19 ноября 2014

Деревья выражений, безусловно, способ использовать большую часть кода, генерируемого во время выполнения.Однако вы должны четко понимать, что он ограничен и не дает вам доступа ко всей силе языка MSIL.Так что LGC и ILGenerator, безусловно, останутся для более сложных задач.

0 голосов
/ 30 сентября 2014

LCG относится к методам, которые могут быть собраны после того, как они выходят за рамки. В выражениях LINQ используется LCG или нормальное отражение emit ... Таким образом, LCG определенно не умер. Также выражения LINQ не поддерживают все, такие как параметры ref, ldtoken, методы экземпляра, свойства и т. Д.

0 голосов
/ 12 апреля 2011

Ну, этот вопрос довольно старый, и я жду, пока завершится tf get ... поэтому я сам на него отвечу.

Да, LCG в большинстве случаев мертв.

Раньше мы использовали немного LCG, и теперь он все преобразован для использования деревьев выражений.Их гораздо проще создавать, код значительно проще поддерживать и отлаживать, а сообщения об ошибках, как правило, более информативны, чем «Операция может дестабилизировать среду выполнения», когда вы ошибаетесь во время разработки.

Но, пожалуй, самое главное, деревья выражений компонуются так, как это делает Reflection.Emit.Это означает, что архитектура компонентов, используемых для генерации кода во время выполнения, может быть более модульной и даже позволять плагинам расширять инфраструктуру генерации кода.

Одна вещь, которую я обнаружил, поддерживается Reflection.Emit, которая не 'В деревьях выражений напрямую поддерживается установка полей .initonly.Это, однако, может быть достигнуто с помощью небольшого вспомогательного класса и вызова его в дереве выражений, например, которое я использовал ниже:

internal static class FieldHelper
{
    public static TTarget AssignInitOnlyField<TTarget, TField>(
        TTarget target, string fieldName, TField value)
    {
        var field = target.GetType().GetField(
            fieldName, 
            BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
        var boxed = (object)target; // required for value type support
        field.SetValue(boxed, value);
        return (TTarget)boxed;
    }
}

Стоит упомянуть одну обратную сторону использования выражениядеревья, а не LCG заключается в том, что построение и компиляция деревьев выражений определенно медленнее, чем непосредственный вывод необработанных кодов операций.Предполагая, что вы кешируете скомпилированные методы, это вряд ли будет серьезной проблемой, но это единственная причина, которая может заставить вас использовать LCG.

...