Можно ли изменить тело метода во время выполнения в .NET? - PullRequest
12 голосов
/ 30 октября 2008

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

Есть предложения?

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

Ответы [ 5 ]

9 голосов
/ 30 октября 2008

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

Но вы также можете сделать это во время выполнения не изменяя тела метода, а используя классы, производные от ContextBoundObject , который является классом .Net, который позволяет вам перехватывать все вызовы, сделанные против него. Вот статья MSDN Magazine , описывающая, как сделать AOP с помощью ContextBoundObject. (Проверьте аспекты в .Net части статьи)

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

Edit:

Существует четвертый вариант использования .Net API неуправляемого профилирования для перехвата метода JIT и замены тел методов перед JIT. Эта техника успешно используется JustMock (Telerik) для макетирования статических методов, не виртуальных методов и даже запечатанных классов.

3 голосов
/ 30 октября 2008

Вы не можете изменить существующий метод во время выполнения, но вы можете создать его с помощью Code DOM на лету и выполнить его. Или вы можете объединить строки кода, скомпилировать их в памяти и запустить.

Я сделал последнее сам (приложение, в котором я разрешил собственный код C #, который был скомпилирован и выполнен в памяти, во время выполнения).

2 голосов
/ 30 октября 2008

Если вы хотите добавить аспекты до или после вызова, взгляните на PostSharp: http://www.postsharp.org/

1 голос
/ 30 октября 2008

A несколько похожий вопрос был задан ранее (хорошо, так что мое решение было несколько похоже). PostSharp уже упоминалось, но есть и эта очень применимая статья LinFu о CodeProject Я нашел интересную при исследовании проблемы.

0 голосов
/ 30 октября 2008

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

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

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

...