3

我今天读到了这个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删除了?这对我来说没有任何意义!

4

4 回答 4

5

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

[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);
    }*/ 
}
于 2009-01-04T12:37:28.853 回答
5

扩展马克的答案。

这绝对是“设计”。理解这一点的合理化的最好方法是考虑这段代码取代了什么。这个特性以许多更简洁的方式采用了条件编译代码的方式。

例如,

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

或者其他版本

#define f1(x) ...

在非调试情况下,显然没有副作用。这与 [Conditional] 代码的行为相同。我同意这绝对不像第一个例子那么清楚,但它和第二个例子一样清楚。

于 2009-01-04T15:47:34.570 回答
1

我想这是由于编译器实现的容易性。

无论如何我都会害怕这样的代码(即使它按你的预期工作)并将它写成

++a;
f1(a);

为了清楚起见。你总能看到什么被执行,什么没有被执行。

于 2009-01-04T11:49:09.370 回答
1

我还怀疑这种行为被设计为与 C 预处理器宏相同,通常设置为在不使用时不评估参数。

于 2009-01-04T13:48:11.360 回答