是否有类似于PostSharp - Infuse C#预编译器的解决方案,允许我在编译时修改代码?
下面是一个伪代码。
[InterceptCallToConstructors]
void Method1(){
Person Eric = new Person("Eric Bush");
}
InterceptCallToConstructors(ConstructorMethodArgs args){
if(args.Type == typeof(Person))
if(PersonInstances++ > 10 ) args.ReturnValue = null;
}在这个例子中,我们看到如果创建了10个人以上,那么Eric不应该包含一个新的Person类。
经过一些研究,我找到了两个解决方案PostSharp和Infuse。使用Infuse,它非常复杂,很难检测出有多少个人的实例,无论怎样,使用PostSharp,它都是要检测的一行代码。
我尝试使用PostSharp来实现AOP,但是PostSharp目前不支持拦截对Constructor方面的调用。
据我所知,Roslyn不支持在编译时修改代码。
发布于 2014-12-06 22:56:36
这将是一个“自定义预处理器”的答案,它修改源代码以实现OP的效果。
我们的DMS软件重组工具包和它的C#前端可以做到这一点。
DMS提供从源到源的转换,转换编码为
if you see *this*, replace it by *that*这是以下列形式写成的:
rule xxx pattern_parameters
this_pattern
-> that_pattern ;"->“发音为”用:-}替换“
DMS对AST进行操作,因此包括解析步骤(从文本到AST)、树转换步骤和生成最终答案的prettyprinting步骤(从文本到文本)。
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规范中的一个bug;他似乎增加了是否创建新Person实例的计数,这肯定不是他的意图)。我们必须确定PersonInstance的位置;它不能只是在以太中浮动。在本例中,我建议它是类的静态成员。
详细信息:每个规则都有一个名称("intercept_constructor",从OP中窃取)。它引用一个句法类别(“表达式”),其句法形状为"new (\a)",迫使它只匹配作为表达式的构造函数调用。规则中的引号是元引号;它们区分规则语言的语法和目标语言的语法(本例中为C#)。反斜杠是元转义;在元引号中的\c与元引号之外的c相同,对于\a也是如此。
在一个非常大的系统中,可能有几个人类。我们希望确保得到正确的类;可能需要通过提供路径将引用的类限定为特定类。OP通过注释提示了这一点。如果要检查包含方法上是否存在注释,则需要自定义特殊谓词来请求。DMS为编写这样的谓词提供了完整的工具,包括完全访问AST,这样谓词就可以在搜索匹配的注释时上下爬升。
发布于 2014-12-15 09:29:48
https://stackoverflow.com/questions/27333277
复制相似问题