首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何编织C#代码来拦截对构造函数的调用?也许是定制的预处理器或者罗斯林

如何编织C#代码来拦截对构造函数的调用?也许是定制的预处理器或者罗斯林
EN

Stack Overflow用户
提问于 2014-12-06 15:38:28
回答 2查看 1.4K关注 0票数 4

是否有类似于PostSharp - Infuse C#预编译器的解决方案,允许我在编译时修改代码?

下面是一个伪代码。

代码语言:javascript
复制
[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不支持在编译时修改代码。

EN

回答 2

Stack Overflow用户

发布于 2014-12-06 22:56:36

这将是一个“自定义预处理器”的答案,它修改源代码以实现OP的效果。

我们的DMS软件重组工具包和它的C#前端可以做到这一点。

DMS提供从源到源的转换,转换编码为

代码语言:javascript
复制
if you see *this*, replace it by *that*

这是以下列形式写成的:

代码语言:javascript
复制
rule xxx pattern_parameters
    this_pattern
    ->  that_pattern ;

"->“发音为”用:-}替换“

DMS对AST进行操作,因此包括解析步骤(从文本到AST)、树转换步骤和生成最终答案的prettyprinting步骤(从文本到文本)。

OP似乎想修改构造函数调用站点(他不能修改构造函数;没有办法让它返回"null")。为了完成OP的任务,他将为DMS提供以下源到源转换规范:

代码语言:javascript
复制
       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,这样谓词就可以在搜索匹配的注释时上下爬升。

票数 1
EN

Stack Overflow用户

发布于 2014-12-15 09:29:48

如果在KRuntime (-> ASP.NET 5)之上运行,则可以通过实现ICompileModule组装中性界面来连接编译。

我建议你看看:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27333277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档