ConditionalAttribute 是否应该删除整行,或者只是方法调用?
根据 ConditionalAttribute
< 上的文档/a> 类:
将 ConditionalAttribute 应用于 方法向编译器表明 不应该调用该方法 编译成微软中间版 语言 (MSIL) 除非有条件 关联的编译符号 定义了 ConditionalAttribute。
对我来说,这意味着 Conditional
属性仅改变单个方法调用级别的行为。但请考虑以下代码片段:
class InstanceType
{
public InstanceType DoSideEffects()
{
Console.WriteLine("Side effects!");
return this;
}
public InstanceType DoMoreSideEffects()
{
Console.WriteLine("More side effects!");
return this;
}
[Conditional("DEBUG")]
public void ConditionalMethod()
{
Console.WriteLine("Conditional method run.");
}
}
class Program
{
static void Main()
{
var x = new InstanceType();
// The compiler appears to strip out this entire line
// in a Release build.
x.DoSideEffects().DoMoreSideEffects().ConditionalMethod();
var y = new InstanceType();
// When each method call appears on its own line,
// the first two methods are included as expected.
y.DoSideEffects();
y.DoMoreSideEffects();
y.ConditionalMethod();
}
}
比较调试和发布版本的输出:
DEBUG RELEASE Side effects! Side effects! More side effects! More side effects! Conditional method run. Side effects! More side effects! Conditional method run.
此行为是否在某处指定? 我曾认为,除了读取“条件方法”的行之外,两个版本都应该具有相同的输出跑步。”
According to the documentation on the ConditionalAttribute
class:
Applying ConditionalAttribute to a
method indicates to compilers that a
call to the method should not be
compiled into Microsoft intermediate
language (MSIL) unless the conditional
compilation symbol that is associated
with ConditionalAttribute is defined.
To me this is saying that the Conditional
attribute only alters behavior at the individual method call level. But consider the following code snippet:
class InstanceType
{
public InstanceType DoSideEffects()
{
Console.WriteLine("Side effects!");
return this;
}
public InstanceType DoMoreSideEffects()
{
Console.WriteLine("More side effects!");
return this;
}
[Conditional("DEBUG")]
public void ConditionalMethod()
{
Console.WriteLine("Conditional method run.");
}
}
class Program
{
static void Main()
{
var x = new InstanceType();
// The compiler appears to strip out this entire line
// in a Release build.
x.DoSideEffects().DoMoreSideEffects().ConditionalMethod();
var y = new InstanceType();
// When each method call appears on its own line,
// the first two methods are included as expected.
y.DoSideEffects();
y.DoMoreSideEffects();
y.ConditionalMethod();
}
}
Compare the outputs of Debug and Release builds:
DEBUG RELEASE Side effects! Side effects! More side effects! More side effects! Conditional method run. Side effects! More side effects! Conditional method run.
Is this behavior specified somewhere? I had thought that both builds were supposed to have the same output except for the lines reading "Conditional method run."
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有趣的功能:-)我从来没有注意到这一点。
我看了IL。我相信,这并不能解释行为(编译过程),但它无论如何都记录了结果。
整个 C# 代码行在 IL 中明显被遗漏:
创建(x 变量)、存储
位于位置 0 并已加载。然后
三种方法的应用
依次:DoSideEffects()、
DeMoreSideEffects() 和
ConditionalMethod()
对我来说,这看起来真的像一个错误。似乎可以在 IL 中排除 ConditionalMethod() 调用。但看来你是对的,整条线都被遗漏了。
Interessting feature :-) I've never noticed that.
I've taken a look at the IL. This doesn't explain the behaviour (the compilation process), but it documents the result anyway, I believe.
The whole C# code line is clearly left out in the IL:
is created (the x variable), stored
at location 0 and loaded. Afterwards
the three methods are applied
successively: DoSideEffects(),
DeMoreSideEffects(), and
ConditionalMethod()
To me, this looks like a bug, really. It seems that it would have been possible to just exclude the ConditionalMethod() call in the IL. But it seems that you are right, that the whole line is left out.
抱歉拖了这么旧的帖子,但我刚刚遇到了同样的事情,这是我能找到的关于这个问题的唯一讨论。
我有一种预感,知道发生了什么事。
[Conditional]
正在剥离对ConditionalMethod()
的调用以及作为传递给它的参数的任何表达式(根据文档,以及上面链接的其他线程)。我的猜测是隐式
this
参数的处理方式完全相同。在 x.DoSideEffects().DoMoreSideEffects().ConditionalMethod(); 行中,作为this
传递的表达式为x.DoSideEffects().DoMoreSideEffects( )
它被尽职地剥离,消除了副作用。如果我们重写为伪代码,明确地将
this
作为第一个参数传递给每个方法,它就会变得更加清晰:ConditionalMethod( DoMoreSideEffects( DoSideEffects( x )));
Sorry drag up such an old post, but I just encountered the same thing and this was the only discussion of this issue that I could find.
I have a hunch as to what is going on. The
[Conditional]
is stripping the call toConditionalMethod()
as well as any expressions that act as parameters passed to it (as per the documentation, and the other thread linked above).My guess is that the implicit
this
parameter is being treated exactly the same way. In the linex.DoSideEffects().DoMoreSideEffects().ConditionalMethod();
the expression that is passed asthis
isx.DoSideEffects().DoMoreSideEffects()
which is dutifully stripped, eliminating the side effects.If we rewrite into pseudo code where we explicitly pass
this
as the first parameter to each method it becomes much clearer:ConditionalMethod( DoMoreSideEffects( DoSideEffects( x )));