14

次のコードを試しました:

class Magic {
   [Conditional("DEBUG")]
   public static void DoMagic( int stuff )
   {
   }
   public static int ComputeMagic()
   {
      throw new InvalidOperationException();
   }
}
class Program
{
   static void Main(string[] args)
   {
      Magic.DoMagic(Magic.ComputeMagic());
   }
}

リリースビルドでは例外がスローされないように見えるため、 でマークされたメソッドへの呼び出しConditionalAttributeが削除されるだけでなく、パラメーターの計算も削除されます。

そのような動作は保証されていますか?

4

2 に答える 2

19

Yes, argument evaluation is removed when DEBUG is not defined (which is typical in Release builds).

From https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/attributes#reserved-attributes:

シンボルが定義されている場合、呼び出しが含まれます。それ以外の場合、呼び出し (呼び出しのパラメーターの評価を含む) は省略されます。

于 2014-02-21T13:14:29.583 に答える
11

はい、すべて削除されます。これは、(たとえば) ロギングにのみ関連する高価な計算を回避するのに最適ですが、必要な副作用を削除しないように注意する必要があることを意味します。例えば:

Trace(SomethingCritical());

は次のものとは大きく異なります。

var result = SomethingCritical();
Trace(result);

またはあなたの特定のケースでは:

DoMagic(ComputeMagic()); // everything here done only if DEBUG symbol defined

var result = ComputeMagic(); // always done
DoMagic(result); // done only if DEBUG symbol defined

仕様§17.4.2から(強調鉱山):

シンボルが定義されている場合、呼び出しが含まれます。それ以外の場合、呼び出し (レシーバーの評価と呼び出しのパラメーターを含む) は省略されます。

于 2014-02-21T13:17:20.547 に答える