Это легко сделать с помощью системы преобразования программ.
DMS Software Reengineering Toolkit - это система преобразования программ общего назначения, которая может использоваться со многими языками (C ++, COBOL, Java, EcmaScript, Fortran, ..), а также, в частности, с C #.
DMS анализирует исходный код, создает деревья абстрактного синтаксиса и позволяет применять шаблоны от источника к источнику для преобразования кода из одной программы на C # в другую с любыми желаемыми свойствами. Правило преобразования для точного выполнения указанной вами задачи:
domain CSharp.
insert_trace():method->method
"[Trace]
\visibility \returntype \methodname(string \parametername)
{ \body } "
->
"\visibility \returntype \methodname(string \parametername)
{ Log.Trace(\CSharpString\(\methodname\),
\CSharpString\(\parametername\),
\parametername);
\body } "
Кавычки (") не являются кавычками CSharp, скорее они являются" доменными кавычками "и указывают, что содержимое внутри кавычек является синтаксисом CSharp (потому что мы сказали" domain CSharp "). The \ foo нотации являются мета-синтаксисом.
Это правило сопоставляет AST, представляющий указанный вами метод с аннотацией [Trace], и переписывает этот AST в отслеживаемую форму. Полученный AST затем печатается обратно в исходную форму, которую вы можете скомпилировать. Вам, вероятно, нужны другие правила для обработки других комбинаций аргументов; на самом деле, вы, вероятно, обобщите обработку аргументов, чтобы получить (где это практически возможно) строковое значение для каждого скалярного аргумента.
Должно быть ясно, что вы можете делать намного больше, чем просто регистрировать с этим, и намного больше, чем просто аспектно-ориентированное программирование, поскольку вы можете выражать произвольные преобразования, а не только действия до и после.