「オン」の場合にのみ実行される「デバッグのみ」のコード


93

デバッグ担当者が要求した場合にのみ実行されるC#の「デバッグ専用」コードを追加したいと思います。C ++では、以前は次のようなことをしていました。

void foo()
{   
  // ...
  #ifdef DEBUG
  static bool s_bDoDebugOnlyCode = false;
  if (s_bDoDebugOnlyCode)
  {
      // Debug only code here gets executed when the person debugging 
      // manually sets the bool above to true.  It then stays for the rest
      // of the session until they set it to false.
  }
  #endif
 // ...
}

ローカルの統計がないため、C#ではまったく同じことはできません。

質問:C#でこれを達成するための最良の方法は何ですか?

  1. C#プリプロセッサディレクティブ(#if/#endif DEBUG)でプライベートクラスの静的フィールドを使用する必要がありますか?
  2. (コードを保持するために)Conditional属性を使用し、次に(C#プリプロセッサディレクティブで囲まれていない)プライベートクラスの静的フィールドを使用する必要があります#if/#endif DEBUGか?
  3. 他に何か?

回答:


145

インスタンス変数は、おそらくあなたが望むことをする方法でしょう。プログラム(または静的メモリモデルによってはスレッド)の存続期間中同じ値を永続化するように静的にしたり、オブジェクトインスタンスの存続期間にわたって制御する通常のインスタンス変数にすることができます。そのインスタンスがシングルトンの場合、それらは同じように動作します。

#if DEBUG
private /*static*/ bool s_bDoDebugOnlyCode = false;
#endif

void foo()
{   
  // ...
#if DEBUG
  if (s_bDoDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }
#endif
 // ...
}

完全を期すために、プラグマ(プリプロセッサーディレクティブ)は、プログラムフローを制御するために使用するのは少々扱いにくいと考えられています。.NETには、「条件付き」属性を使用して、この問題の半分に対する組み込みの回答があります。

private /*static*/ bool doDebugOnlyCode = false; 
[Conditional("DEBUG")]
void foo()
{   
  // ...    
  if (doDebugOnlyCode)
  {
      // Code here gets executed only when compiled with the DEBUG constant, 
      // and when the person debugging manually sets the bool above to true.  
      // It then stays for the rest of the session until they set it to false.
  }    
  // ...
}

プラグマなし、はるかにクリーン。欠点は、Conditionalはメソッドにのみ適用できるため、リリースビルドでは何もしないブール変数を処理する必要があることです。変数はVS実行ホストからトグルするためだけに存在し、リリースビルドではその値は問題ではないため、かなり無害です。


2
最後に質問全体を読んだ人。おかげで、大丈夫です-(2つのプリプロセッサセクションを用意する必要がある)長い解決策のように見えましたが、おそらくそれは、私が望んでいることに対してC#が実行できる最善の方法です。
Matt Smith、

6
ええ。プリプロセッサディレクティブをさらに2行追加したからといって、これを長く呼ぶことはしません。
KeithS、

4
問題全体を解決しないものを支持して、3年前に承認された回答に反対票を投じてくれたPatrickに感謝します。条件付き属性は、メソッドが非デバッグモードで実行されるのを防ぐだけです。OPはそれだけでなく、デバッガーを使用してコードを「オン」にできることを望んでいました。また、使用されるgokkorのタグはコンパイルされません。
KeithS 2014年

2
プリプロセッサは、プログラムがデバッグモードでコンパイルされているかどうかを通知しますが、デバッガが実際に実行されているかどうかは通知しないことに注意してください。
シェーン

65

あなたが探しているのは

[ConditionalAttribute("DEBUG")]

属性。

たとえば、次のようなメソッドを記述したとします。

[ConditionalAttribute("DEBUG")]
public static void MyLovelyDebugInfoMethod(string message)
{
    Console.WriteLine("This message was brought to you by your debugger : ");
    Console.WriteLine(message);
}

独自のコード内でこのメソッドを呼び出すと、デバッグモードでのみ実行されます。プロジェクトをリリースモードでビルドした場合、「MyLovelyDebugInfoMethod」の呼び出しでさえ無視され、バイナリからダンプされます。

もう1つ、実行時にコードが現在デバッグされているかどうかを判断する場合、現在のプロセスがJITによってフックされているかどうかを確認することもできます。しかし、これはすべて別のケースです。これがあなたがやろうとしていることなら、コメントを投稿してください。


3
属性を使用する場合、接尾辞「属性」を記述する必要はありません。条件付き= ConditionalAttribute。属性クラスは「属性」で終わる必要がありますが、コードで属性として使用すると省略できます。接尾辞を省略すると読みやすくなります。
Eric Ouellet

23

プロセスにデバッガーが接続されている場合にのみ実行するコードが必要な場合は、これを試すことができます。

if (Debugger.IsAttached)
{
     // do some stuff here
}

ありがとうございました!これはまさに私が欲しかったものです:デバッグ時にコンソールウィンドウを閉じないように、最後にConsole.ReadLine()を実行してください。
VVS

4

私はそれが言及する価値かもしれないと思う[ConditionalAttribute]にあるSystem.Diagnostics;名前空間。私が得たとき、私は少しつまずきました:

Error 2 The type or namespace name 'ConditionalAttribute' could not be found (are you missing a using directive or an assembly reference?)

初めて使用した後(私はそれがであったと思ったSystem)。


3

デバッグするかどうかを知りたい場合は、プログラムのどこでも。これを使って。

グローバル変数を宣言します。

bool isDebug=false;

デバッグモードをチェックするための関数を作成する

[ConditionalAttribute("DEBUG")]
    public static void isDebugging()
    {
        isDebug = true;
    }

initializeメソッドで関数を呼び出します

isDebugging();

プログラム全体で。デバッグの確認と操作ができます。お役に立てれば!


1
私の知る限り:これとその変種は、プログラムがデバッグフラグを設定してコンパイルされたかどうかを確実に知る唯一の方法です。
LosManos 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.