3

Conditional今日、属性について読みました。MSDNによると:

メソッドへの適用は、関連付けられている条件付きコンパイル シンボルが定義されConditionalAttributeていない限り、メソッドへの呼び出しを Microsoft Intermediate Language (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

マークの答えを拡張します。

これは間違いなく「By Design」です。この合理化を理解する最善の方法は、このコードが何に取って代わったかを考えることです。この機能は、多くのよりクリーンな方法で、条件付きでコンパイルされたコードの方法を取ります。

例えば、

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

または別のバージョン

#define f1(x) ...

非デバッグの場合、明らかに副作用はありません。これは、[Conditional] コードの場合と同じ動作です。最初の例ほど明確ではないことに同意しますが、2番目の例ほど明確です。

于 2009-01-04T15:47:34.570 に答える
1

また、この動作は C プリプロセッサ マクロと同じように設計されているのではないかと思います。C プリプロセッサ マクロは通常、使用されていないときに引数を評価しないように設定されています。

于 2009-01-04T13:48:11.360 に答える
1

これは、コンパイラの実装の容易さによるものだと思います。

とにかくそのようなコードを恐れて(たとえそれが期待どおりに機能したとしても)、次のように記述します

++a;
f1(a);

明確にするために。何が実行され、何が実行されていないかを常に確認できます。

于 2009-01-04T11:49:09.370 に答える