Можно ли изменить тело метода во время выполнения в .NET?

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

Какие-либо предложения?

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
4 499
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Планируете ли вы сделать это для произвольных типов? Я бы не предполагал, что вы собираетесь украсить методы атрибутом.

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

В общем, однако, если вы не приступите к созданию файлов кода и компиляции динамических сборок во время выполнения, то, что вы хотите сделать, не может быть выполнено. Вероятно, существуют гораздо более практичные принципы и шаблоны объектно-ориентированного программирования, которые вы можете использовать для достижения почти такого же результата.

Вы не можете изменить существующий метод во время выполнения, но вы можете создать его с помощью 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, который я нашел интересным при исследовании проблемы.

Другие вопросы по теме