如何编织C#代码来拦截对构造函数的调用?也许是自定义预处理器或Roslyn
有没有类似于[PostSharp]-[Infuse-C#的预编译器]的解决方案,可以让我在编译时修改代码 下面是一个伪代码如何编织C#代码来拦截对构造函数的调用?也许是自定义预处理器或Roslyn,c#,preprocessor,metaprogramming,aop,roslyn,C#,Preprocessor,Metaprogramming,Aop,Roslyn,有没有类似于[PostSharp]-[Infuse-C#的预编译器]的解决方案,可以让我在编译时修改代码 下面是一个伪代码 [InterceptCallToConstructors] void Method1(){ Person Eric = new Person("Eric Bush"); } InterceptCallToConstructors(ConstructorMethodArgs args){ if(args.Type == typeof(Person))
[InterceptCallToConstructors]
void Method1(){
Person Eric = new Person("Eric Bush");
}
InterceptCallToConstructors(ConstructorMethodArgs args){
if(args.Type == typeof(Person))
if(PersonInstances++ > 10 ) args.ReturnValue = null;
}
在本例中,我们看到,如果创建了10个以上的Person,则Eric不应包含新Person类
经过一些研究,我找到了两种解决方案,一种是PostSharp,另一种是Infuse。
使用Infuse很复杂,很难检测出有多少个人的实例,而PostSharp只需检测一行代码
我曾尝试使用PostSharp进行AOP,但PostSharp目前不支持拦截对构造函数方面的调用。据我所知,Roslyn不支持在编译时修改代码 这将是一个“自定义预处理器”的答案,它修改源代码以实现OP的效果 我们的智能手机可以做到这一点 DMS提供源到源的转换,转换编码为
if you see *this*, replace it by *that*
这是以以下形式书写的:
rule xxx pattern_parameters
this_pattern
-> that_pattern ;
“->”发音为“替换为::-}”
DMS在ASTs上运行,因此包括解析步骤(文本到ASTs)、树转换步骤和生成最终答案的预打印步骤(ASTs到文本)
OP似乎想要修改构造函数调用站点(他无法修改构造函数;无法使其返回“null”)。为了完成OP的任务,他将向DMS提供以下源到源转换规范:
default domain CSharp~v5; -- says we are working with C# syntax (and need the C# front end)
rule intercept_constructor(c: IDENTIFIER, a:arguments): expression
" new \c (\a) "
-> " \c.PersonInstances==10?null:(PersonInstances++,new \c (\a)) "
if c == "Person"; -- one might want to force c to be on some qualified path
该规则所做的是找到任意形式的匹配构造函数调用语法,并将其替换为检查OP的前提条件的条件表达式,如果有太多的Person实例,则返回null(我们在这里修复了OP规范中的一个错误;无论是否创建了新Person实例,他似乎都会增加计数,这肯定不是他的意图).我们必须限定PersonInstance的位置;它不能只是在以太中漂浮。在本例中,我建议它是类的静态成员
详细信息:每个规则都有一个名称(“intercept\u constructor”,从OP偷来)。它指的是一个语法类型(“表达式”),语法形状为“new\c(\a),强制它只匹配作为表达式的构造函数调用。规则中的引号是元引号;它们将规则语言的语法与目标语言的语法(在本例中为C#)区分开来。反斜杠是元转义\元引号中的c与元引号外的c在规则中的思维方式相同,类似于\a
在一个非常大的系统中,可能有几个Person类。我们要确保我们得到了正确的答案;可能需要通过提供路径将引用的类限定为特定类。OP使用注释提示这一点。如果要检查包含方法上是否存在注释,则需要自定义特殊谓词来进行检查。DMS为编写这样的谓词提供了完整的工具,包括对AST的完全访问,因此谓词可以在搜索匹配注释时向上或向下爬升。如果您在KRuntime(->ASP.NET 5)上运行,则可以通过实现 我建议你去:
- aop