web-dev-qa-db-ja.com

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

デバッグする人が要求した場合にのみ実行される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属性を使用し、プライベートクラスの静的フィールドを使用する必要があります(not C#プリプロセッサディレクティブ#if /#endif DEBUGで囲まれていますか?)。
  3. 他に何か?
80
Matt Smith

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

#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実行ホストから切り替えるためだけに存在し、リリースビルドではその値は重要ではないので、かなり無害です。

130
KeithS

あなたが探しているのは

[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にフックされているかどうかを確認することもできます。しかし、これはすべて別のケースです。これがあなたがやろうとしていることならコメントを投稿してください。

59
gokkor

プロセスにアタッチされたデバッガーがある場合にのみ実行するコードが必要な場合、これを試すことができます。

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

_[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
XyberICE

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

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

bool isDebug=false;

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

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

初期化メソッドで関数を呼び出します

isDebugging();

今、プログラム全体で。デバッグを確認して、操作を実行できます。お役に立てれば!

3
Mohamed Alikhan