デバッグの時だけデバッグ用のコードを挿入したいというケースはよくあります。そのような時、リリースでビルドする前に手作業でそのコードを削除していたのでは面倒なだけでなく、バグの原因にもなります。ここでは、デバッグでビルドした時だけ指定したコードがコンパイルされるようにする方法を紹介します。
まずは、#If...Thenディレクティブ(C#では、#if...#endifディレクティブ)を使う方法を紹介します。
次のコードでは、デバッグ(ソリューション構成が「Debug」)でビルドされた時のみ「Console.WriteLine...」のコードがコンパイルされるようにしています。このように、デバッグビルドでだけコンパイルさせたい部分を「#If DEBUG Then」と「#End If」で囲みます。
#If DEBUG Then Console.WriteLine("デバッグバージョンです。") #End If
#if DEBUG Console.WriteLine("デバッグバージョンです。"); #endif
「#If DEBUG Then」の意味は、「DEBUGが定義されていれば」ということです。「DEBUG」というのは条件付きコンパイル定数(シンボル)で、デバッグビルドの時に定義されるようになっています。
ただし、設定によってはデバッグビルドでもDEBUGが定義されない可能性もあります。Visual Studioでプロジェクトのプロパティを表示し(メニューの[プロジェクト]-[(プロジェクト)のプロパティ]で表示できます)、「ビルド」タブを選択してください。「構成」が「Debug」の時に「DEBUG定数の定義」にチェックが入っていれば、デバッグビルドでDEBUGが定義されます。
また、「構成」が「Release」の時には「DEBUG定数の定義」にチェックが入っていないことも確認してください。
補足:.NET Framework 1.1以下では、プロジェクトのプロパティで「プロパティページダイアログ」の[構成プロパティ]-[ビルド]を選択し、[コード生成]-[条件付きコンパイル定数]に"DEBUG"があればDEBUGが定義されます。
シンボルを定義する方法について補足します。上記のようにVisual Studioの設定を使う以外にも、シンボルを定義する(あるいは未定義にする)方法は幾つかあります。
コマンドラインを使ってビルドする場合は、/defineコンパイラオプションでシンボルの定義ができます。DEBUGを定義する場合は、「/define:DEBUG」とします。
環境変数で定義することもできます。DEBUGを定義する場合は、変数を「DEBUG」値を「1」とした環境変数を作成します。
コード内でDEBUGを定義することもできます。この場合は、VB.NETでは#Constディレクティブ、C#では#defineディレクティブを使います。このように定義されたシンボルは、そのファイル内でのみ有効です。
以下に例を示します。
'#Const DEBUG = True 'がファイルの先頭に記述されているものとする #If DEBUG Then Console.WriteLine("DEBUGが定義されています") #End If
//#define DEBUG //がファイルの先頭に記述されているものとする #if DEBUG Console.WriteLine("DEBUGが定義されています"); #endif
ちなみに定義されているシンボルを未定義にするには、VB.NETでは「#Const DEBUG = False」とし、C#では#undefディレクティブを使用します。
なお、DEBUGやTRACEだけでなく、上記の方法で独自のシンボルを定義することもできます。
今までの説明では「#If...Then...#End If」(C#では、「#if...#endif」)のみを使用しましたが、「#If...Then...#ElseIf...#Else...#End If」(C#では、「#if...#elif...#else...#endif」)という使い方もできます。
以下にその例を示します。
#If DEBUG Then Console.WriteLine("DEBUGが定義されています") #ElseIf TRACE Then Console.WriteLine("TRACEが定義されています") #Else Console.WriteLine("DEBUGもTRACEも定義されていません") #End If
#if DEBUG Console.WriteLine("DEBUGが定義されています"); #elif TRACE Console.WriteLine("TRACEが定義されています"); #else Console.WriteLine("DEBUGもTRACEも定義されていません"); #endif
ConditionalAttributeをメソッドに適用すると、指定したシンボルが定義されている時だけ、そのメソッドの呼び出しがコンパイルされます。これを使って、指定したメソッドの呼び出しがデバッグビルドの時だけコンパイルされるようにすることができます。
次の例では、ShowMessageメソッドの呼び出しがデバッグビルドの時(DEBUGが定義されている時)のみコンパイルされるようにしています。なお、Conditional属性を適用できるメソッドは、戻り値なし(void型の戻り値)のメソッドです。
'Imports System.Diagnostics 'DEBUGが定義されている時のみ有効となる <Conditional("DEBUG")> _ Public Shared Sub ShowMessage(ByVal str As String) Console.WriteLine(str) End Sub
//using System.Diagnostics; //DEBUGが定義されている時のみ有効となる [Conditional("DEBUG")] public static void ShowMessage(string str) { Console.WriteLine(str); }
Conditional属性はメソッドとクラスに適用できます。.NET Framework 1.1以下では、メソッドだけに適用できます。
簡単な情報の出力だけならば、Debugクラスを使うのが手っ取り早いです。DebugクラスのすべてのメソッドにはConditional属性が適用されています。詳しくは「VB6のDebug.Printと同じ事を行うには?」をご覧ください。