如何在编译时注入C#代码?

如何在编译时注入C#代码?,c#,.net,reflection,aop,trace,C#,.net,Reflection,Aop,Trace,我希望能够用一个自定义的Trace属性来修饰任何方法,并且在编译时应该向该方法注入一些代码 例如: [Trace] public void TracedMethod(string param1) { //method body } 应成为: public void TracedMethod(string param1) { Log.Trace("TracedMethod", "param1", param1); //method body } 在这种情况下,注入的代码取决于

我希望能够用一个自定义的
Trace
属性来修饰任何方法,并且在编译时应该向该方法注入一些代码

例如:

[Trace]
public void TracedMethod(string param1)
{
   //method body
}
应成为:

public void TracedMethod(string param1)
{
   Log.Trace("TracedMethod", "param1", param1);
   //method body
}
在这种情况下,注入的代码取决于方法名称和方法参数,因此应该可以推断出这些信息


有人知道如何做到这一点吗?要在C#中进行面向方面的编程,可以使用


(甚至显示了一个
跟踪
示例,就像您要求的那样!)

这可以通过程序转换系统轻松完成

是一个通用程序转换系统,可与多种语言(C++、COBOL、Java、EcmaScript、Fortran等)一起使用,也可与C#一起使用

DMS解析源代码,构建抽象语法树,并允许您将源代码应用于源代码模式,以将代码从一个C#程序转换为另一个具有任何属性的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语法(因为我们说的是“域CSharp”)。foo符号是元语法

此规则与表示使用[Trace]指定的方法的AST匹配注释,并将该AST重写到跟踪表单中。然后,生成的AST被预打印回源表单,您可以对其进行编译。您可能需要其他规则来处理其他参数组合;事实上,您可能需要对参数处理进行一般化以生成(如果可行)每个标量参数的字符串值


应该清楚的是,你可以做的不仅仅是记录日志,也不仅仅是面向方面的编程,因为你可以表达任意转换,而不仅仅是前后操作。

我从来没有研究过后锐化代码的性能,但是如果后锐化垫片产生了显著的变化,我会感到惊讶。我可以“我不想用PostSharp Loas做我想做的事(PostSharp的AOP插件),但我可以通过为PostSharp编写自定义AOP插件来实现。虽然PostSharp LOA可能会影响运行时性能,但我的自定义插件不会影响运行时性能,因为它只在编译时运行。虽然这听起来非常有用,但我将首先尝试PostSharp,因为它是免费的,可以访问源代码。我还可以随时重命名属性指向,不要打断任何东西。为什么你因为属性重命名而明显反对?如果你想重命名属性,你实际上也可以编写一个程序转换来实现这一点。