当前位置:  开发笔记 > 编程语言 > 正文

为什么.NET的条件属性导致副作用被删除?

如何解决《为什么.NET的条件属性导致副作用被删除?》经验,为你挑选了2个好方法。

Conditional今天读到了这个属性.根据MSDN:

应用于ConditionalAttribute方法指示编译器不应将对方法的调用编译为Microsoft中间语言(MSIL),除非ConditionalAttribute定义了与之关联的条件编译符号.

好.这很清楚.因此不会编译对该方法调用.但副作用呢?

[Conditional("UndefinedCondition")]
static void f1(int x) { Console.WriteLine(x); }

static int a = 0;
static void f2() { f1(++a); }

因此,当f2被调用时,f1应该删除调用.但为什么也被++a删除了?这对我没有任何意义!



1> Marc Gravell..:

是的,参数所需的任何调用也会被删除.这意味着对于典型的用例(调试版本),您将删除整个表达式,这通常是预期的.

基本上,在使用任一[Conditional]方法同等(在C#3.0中)部分方法时,您需要非常小心- 如果未实现部分方法的另一半,则这些方法具有非常相似的行为.作为示例(对于部分方法),请参见下文.请注意,HasSideEffect()删除了调用(取消注释另一半Bar以查看它是否有效):

using System;
partial class Foo {
    partial void Bar(string value);
    static void Main() {
        Foo foo = new Foo();
        foo.Bar(HasSideEffect());
    }
    static string HasSideEffect() {
        Console.WriteLine("hello");
        return "world";
    }
}

partial class Foo {
    /* uncomment this
    partial void Bar(string value) {
        Console.WriteLine(value);
    }*/ 
}



2> JaredPar..:

扩展Marc的答案.

这绝对是"按设计".理解这种合理化的最好方法是考虑这个代码取而代之的是什么.这个功能以许多更清晰的方式采用了有条件编译的代码.

例如,

#if DEBUG
f1(++a);
#endif

或者另一个版本

#define f1(x) ...

在非调试的情况下,显然没有副作用.这与[条件]代码的行为相同.我同意它肯定不如第一个例子那么清楚,但它与第二个例子一样清晰.

推荐阅读
linjiabin43
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有