Я знаю, что возможно (теоретически) создать новый тип во время выполнения, но можно ли изменить тело метода существующего типа во время выполнения? Мой план (если я смогу заставить это работать) состоит в том, чтобы пометить методы с помощью настраиваемого атрибута, а затем во время выполнения искать методы с этим атрибутом и вставить часть моего собственного кода в тело метода.
Какие-либо предложения?
Я полагаю, что если я не могу заставить этот подход работать, я всегда мог бы использовать виртуальный метод в базовом классе (с атрибутами) в сочетании со статической фабрикой, чтобы выдавать производный динамический тип с помощью моего метода, сгенерированного во время выполнения. в детском классе. Однако это было бы не так чисто для использования.





Планируете ли вы сделать это для произвольных типов? Я бы не предполагал, что вы собираетесь украсить методы атрибутом.
Учитывая это, я думаю, что лучшим подходом было бы определение абстрактных методов в суперклассе для ваших типов. Метод суперкласса может содержать шаблонный код метода и делегировать его конкретным реализациям через абстрактные методы для поведения отдельного типа этого метода.
В общем, однако, если вы не приступите к созданию файлов кода и компиляции динамических сборок во время выполнения, то, что вы хотите сделать, не может быть выполнено. Вероятно, существуют гораздо более практичные принципы и шаблоны объектно-ориентированного программирования, которые вы можете использовать для достижения почти такого же результата.
Вы не можете изменить существующий метод во время выполнения, но вы можете создать его с помощью Code DOM на лету и выполнить его. Или вы можете объединить строки кода, скомпилировать их в памяти и запустить.
Последнее я сделал сам (приложение, в котором я разрешил собственный код C#, который был скомпилирован и выполнен в памяти, во время выполнения).
Если вы хотите добавить аспекты до или после вызова, взгляните на PostSharp: http://www.postsharp.org/
PostSharp, который является посткомпилятором, делает что-то похожее на то, что вы описываете, используя атрибуты для отметки точек внедрения в коде, с той лишь разницей, что он делает это во время компиляции.
Но вы также можете сделать это во время выполнения, не изменяя тела методов, а используя классы, производные от ContextBoundObject, который является классом .Net, который позволяет вам перехватывать все вызовы, сделанные против него. Вот Статья в журнале MSDN, описывающий, как выполнять АОП с помощью ContextBoundObject. (Проверьте часть статьи о аспекты в .Net)
И в качестве третьего варианта вы можете использовать динамическую генерацию кода (Reflection.Emit или CodeDom) в сочетании с атрибутами и виртуальными методами для динамической генерации производных классов, в которые вы можете вставить свой код, но это наиболее болезненный способ сделать это.
Редактировать:
Есть четвертый вариант использования .Net API неуправляемого профилирования для перехвата JIT-процесса метода и замены тела метода перед JIT-процессом. Этот метод успешно используется JustMock (Telerik) для имитации статических методов, не виртуальных методов и даже запечатанных классов.
несколько похожий вопрос был задан ранее (хорошо, мое решение было чем-то похожим). PostSharp уже упоминалось, но есть также очень применимый Статья LinFu на CodeProject, который я нашел интересным при исследовании проблемы.