何年もの間、コンソールにメッセージを書き込むために VB.NET で DEBUG コンパイラ定数を使用してきました。System.Diagnostics.Debug.Write も同様の方法で使用しています。RELEASE がビルド オプションとして使用された場合、これらのステートメントはすべてコンパイラによって除外され、実稼働コードからデバッグ ステートメントのオーバーヘッドが解放されることを常に理解していました。最近、Silverlight 2 Beta 2 を使用しているときに、公開 Web サイトから実行していた RELEASE ビルドに Visual Studio が実際にアタッチされ、コンパイルさえされていないと想定していた DEBUG ステートメントが表示されることに気付きました。さて、私の最初の傾向は、自分の環境に何か問題があると仮定することですが、System.Diagnostics について深い知識を持っている人にも尋ねたいと思います。
7 に答える
推奨される方法は、コンパイラ ディレクティブを使用するのではなく、実際に条件付き属性を使用してデバッグ呼び出しをラップすることです。#ifs はトリッキーになり、奇妙なビルドの問題を引き起こす可能性があります。
条件付き属性の使用例は次のとおりです (C# の場合ですが、VB.NET でも機能します)。
[ Conditional("Debug") ]
private void WriteDebug(string debugString)
{
// do stuff
}
DEBUG フラグを設定せずにコンパイルすると、Debug.Write() で発生していると想定されていたので、WriteDebug への呼び出しはすべて削除されます。
Debug.Write メソッドを調べます。それはでマークされています
[Conditional("DEBUG")]
属性。
ConditionalAttributeの MSDN ヘルプには、次のように記載されています。
指定された条件付きコンパイル シンボルが定義されていない限り、メソッド呼び出しまたは属性を無視する必要があることをコンパイラに示します。
ビルド構成にリリースまたはデバッグのラベルが付いているかどうかは関係ありません。重要なのは、DEBUG シンボルが定義されているかどうかです。
私もこの記事を読みましたが、DEBUG が定義されていない場合、System.Debug 関数で宣言された ConditionalAttribute により、コンパイラがこのコードを完全に除外してしまうのではないかと思いました。TRACE についても同じことが言えると思います。つまり、System.Diagnostics.Debug 関数には、DEBUG と TRACE の ConditionalAttributes が必要です。私はその仮定で間違っていました。別の Trace クラスには同じ機能があり、これらは TRACE 定数に依存する ConditionalAttribute を定義します。
System.Diagnostics.Debug から: _ Public Shared Sub Write (_ message As String _ )
System.Diagnostics.Trace から: _ Public Shared Sub WriteLine ( _ message As String _ )
System.Diagnostics.Debug (または system.Diagnostics.Trace) ステートメントは、#IF DEBUG (または #IF TRACE) 領域に含まれているかのように、実際にはコンパイルに含まれていないという私の最初の仮定は正しかったようです。
しかし、RELEASE ビルド自体がこれに対応していないことも皆さんから学び、確認しました。少なくともまだ不安定な Silverlight プロジェクトでは、"Advanced Compile Options..." に入り、DEBUG が定義されていないことを確認する必要があります。
.NET 1.1/VS2003 から .NET 3.5/VS2008 に移行したため、以前は動作が異なっていたものもあると思いますが、おそらく 2.0/VS2005 で変更されました。
デバッグ情報をコンパイルするか削除するかを選択するには、
プロジェクトのプロパティ ウィンドウで [ビルド] タブに入ります。
適切な構成 (アクティブ/リリース/デバッグ/すべて) を選択し、情報が必要な場合は「DEBUG 定数」にチェックを入れ、必要ない場合はチェックを外してください。
変更を適用して再構築する
私がしていることは、Debug への呼び出しを自分のクラスにカプセル化し、プリコンパイラ ディレクティブを追加することです。
public void Debug(string s)
{
#if DEBUG
System.Diagnostics.Debug(...);
#endif
}
あなたが言ったように、DEBUGコンパイラシンボルを使用すると、実際にはアセンブリからコードが省略されます。
リリース モードでビルドした場合でも、System.Diagnostics.Debug.Write は常に接続されたデバッガーに出力されると思います。MSDN の記事によると:
デバッグに関する情報を Listeners コレクションのトレース リスナーに書き込みます。
出力が必要ない場合は、 Juan が言ったように、Debug.Write への呼び出しを DEBUG 定数でラップする必要があります。
#if DEBUG
System.Diagnostics.Debug.Write(...);
#endif
私の経験では、VB.NET でデバッグとリリースのどちらを選択しても違いはありません。両方の構成にカスタム アクションを追加することもできますが、デフォルトでは同じだと思います。
Release を使用しても、System.Diagnostics.Debug.Write ステートメントは削除されません。