DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

デバッグビルドでのみ特定のコードがコンパイルされるようにする
条件付きコンパイル定数を使用する

デバッグの時だけデバッグ用のコードを挿入したいというケースはよくあります。そのような時、リリースでビルドする前に手作業でそのコードを削除していたのでは面倒なだけでなく、バグの原因にもなります。ここでは、デバッグでビルドした時だけ指定したコードがコンパイルされるようにする方法を紹介します。

#If...Thenディレクティブを使う

まずは、#If...Thenディレクティブ(C#では、#if...#endifディレクティブ)を使う方法を紹介します。

次のコードでは、デバッグ(ソリューション構成が「Debug」)でビルドされた時のみ「Console.WriteLine...」のコードがコンパイルされるようにしています。このように、デバッグビルドでだけコンパイルさせたい部分を「#If DEBUG Then」と「#End If」で囲みます。

ソリューション構成でDebugを選択

VB.NET
コードを隠すコードを選択
#If DEBUG Then
    Console.WriteLine("デバッグバージョンです。")
#End If
C#
コードを隠すコードを選択
#if DEBUG
    Console.WriteLine("デバッグバージョンです。");
#endif

「#If DEBUG Then」の意味は、「DEBUGが定義されていれば」ということです。「DEBUG」というのは条件付きコンパイル定数(シンボル)で、デバッグビルドの時に定義されるようになっています。

ただし、設定によってはデバッグビルドでもDEBUGが定義されない可能性もあります。Visual Studioでプロジェクトのプロパティを表示し(メニューの[プロジェクト]-[(プロジェクト)のプロパティ]で表示できます)、「ビルド」タブを選択してください。「構成」が「Debug」の時に「DEBUG定数の定義」にチェックが入っていれば、デバッグビルドでDEBUGが定義されます。

DEBUG定義の設定

また、「構成」が「Release」の時には「DEBUG定数の定義」にチェックが入っていないことも確認してください。

補足:.NET Framework 1.1以下では、プロジェクトのプロパティで「プロパティページダイアログ」の[構成プロパティ]-[ビルド]を選択し、[コード生成]-[条件付きコンパイル定数]に"DEBUG"があればDEBUGが定義されます。

.NET Framework 1.1以下の場合

シンボルを定義する方法の補足

シンボルを定義する方法について補足します。上記のようにVisual Studioの設定を使う以外にも、シンボルを定義する(あるいは未定義にする)方法は幾つかあります。

コマンドラインを使ってビルドする場合は、/defineコンパイラオプションでシンボルの定義ができます。DEBUGを定義する場合は、「/define:DEBUG」とします。

環境変数で定義することもできます。DEBUGを定義する場合は、変数を「DEBUG」値を「1」とした環境変数を作成します。

コード内でDEBUGを定義することもできます。この場合は、VB.NETでは#Constディレクティブ、C#では#defineディレクティブを使います。このように定義されたシンボルは、そのファイル内でのみ有効です。

以下に例を示します。

VB.NET
コードを隠すコードを選択
'#Const DEBUG = True
'がファイルの先頭に記述されているものとする

#If DEBUG Then
    Console.WriteLine("DEBUGが定義されています")
#End If
C#
コードを隠すコードを選択
//#define DEBUG
//がファイルの先頭に記述されているものとする

#if DEBUG
    Console.WriteLine("DEBUGが定義されています");
#endif

ちなみに定義されているシンボルを未定義にするには、VB.NETでは「#Const DEBUG = False」とし、C#では#undefディレクティブを使用します。

なお、DEBUGやTRACEだけでなく、上記の方法で独自のシンボルを定義することもできます。

#If...Thenディレクティブの補足

今までの説明では「#If...Then...#End If」(C#では、「#if...#endif」)のみを使用しましたが、「#If...Then...#ElseIf...#Else...#End If」(C#では、「#if...#elif...#else...#endif」)という使い方もできます。

以下にその例を示します。

VB.NET
コードを隠すコードを選択
#If DEBUG Then
    Console.WriteLine("DEBUGが定義されています")
#ElseIf TRACE Then
    Console.WriteLine("TRACEが定義されています")
#Else
    Console.WriteLine("DEBUGもTRACEも定義されていません")
#End If
C#
コードを隠すコードを選択
#if DEBUG
    Console.WriteLine("DEBUGが定義されています");
#elif TRACE
    Console.WriteLine("TRACEが定義されています");
#else
    Console.WriteLine("DEBUGもTRACEも定義されていません");
#endif

Conditional属性を使用して、デバッグの時だけメソッドの呼び出しがコンパイルされるようにする

ConditionalAttributeをメソッドに適用すると、指定したシンボルが定義されている時だけ、そのメソッドの呼び出しがコンパイルされます。これを使って、指定したメソッドの呼び出しがデバッグビルドの時だけコンパイルされるようにすることができます。

次の例では、ShowMessageメソッドの呼び出しがデバッグビルドの時(DEBUGが定義されている時)のみコンパイルされるようにしています。なお、Conditional属性を適用できるメソッドは、戻り値なし(void型の戻り値)のメソッドです。

VB.NET
コードを隠すコードを選択
'Imports System.Diagnostics

'DEBUGが定義されている時のみ有効となる
<Conditional("DEBUG")> _
Public Shared Sub ShowMessage(ByVal str As String)
    Console.WriteLine(str)
End Sub
C#
コードを隠すコードを選択
//using System.Diagnostics;

//DEBUGが定義されている時のみ有効となる
[Conditional("DEBUG")] 
public static void ShowMessage(string str) 
{ 
    Console.WriteLine(str); 
}

Conditional属性はメソッドとクラスに適用できます。.NET Framework 1.1以下では、メソッドだけに適用できます。

Debugクラスを使って、デバッグの時だけメッセージを表示する

簡単な情報の出力だけならば、Debugクラスを使うのが手っ取り早いです。DebugクラスのすべてのメソッドにはConditional属性が適用されています。詳しくは「VB6のDebug.Printと同じ事を行うには?」をご覧ください。

  • 履歴:
  • 2012/7/18 全体的に書き直す。
  • 2013/6/11 誤字修正(コメントでご指摘頂きました)。
  • 2013/12/16 ソリューション構成を選択する画像を追加など。
  • 2014/5/12 誤字修正。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。