2010-11-19 7 views
21

これは簡単な質問だと思うので、私は何かが明らかでないと思います。私は実際にプリプロセッサディレクティブを使用することはありませんが、私は誰かのコードを見ていました。プリプロセッサディレクティブを.netで使用するのはいつですか?

だから私はそれがコードがあるMSDNの例hereを見て:

#define DEBUG 
// ... 
#if DEBUG 
    Console.WriteLine("Debug version"); 
#endif 

を私の二つの質問があります:彼らはDEBUGを定義しない理由上記の例では

  • ?私はあなたがデバッグ対リリースモードでコンパイルすると設定された印象の下にいたのですか?
  • #define MYTESTを持っている他の例を見て、それが定義されているかどうかによってコンソールに書き込みますが、これは単に変数を使うこととどのように違いますか?私はここで何が欠けていますか?

答えて

4

実行可能ファイル/ dllに含まれるコードの一部だけをプリプロセッサディレクティブで使用すると、すべてのコードがコンパイルされます。

5

上記の例では、なぜDEBUGを定義していますか?私はあなたがデバッグ対リリースモードでコンパイルすると設定された印象の下にいたのですか?

おそらく例コードなので。それはどのように#ifdefと友人が働くかを実証するためのものです。クイックテストでない限り、ソースファイルにそのようなシンボルを定義することは期待していません。

"#define MYTEST"を持つ他の例を見て、それが定義されているかどうかによってコンソールに書き込みますが、これは単に変数を使用することとどのように違いますか?私はここで何が欠けていますか?

MYTESTがコンパイル時に定義されていない場合、コンパイラは実際#if#endifブロック間のコードを放出しないであろう。したがって、結果として生じるILは小さくなる。

また、これらのは、C#のプリプロセッサディレクティブではありません。

+1

[MSDNはそれらを「プリプロセッサディレクティブ」と呼んでいます。](http://msdn.microsoft.com/en-us/library/ed8yd1ha.aspx) –

+0

しかし、そうではありません。同じ記事:* "コンパイラには別のプリプロセッサがありません" *。 – cdhowie

+4

より正確に言えば、*条件付きコンパイルシンボル*です。 C++で見られるものと似ていますが、C#コンパイラには別のプリプロセッサはありません。 (http://blogs.msdn.com/b/csharpfaq/archive/2004/03/09/86979.aspx) –

2

私は、CLRの代わりにMono環境を使用するときに別の処理を必要とするコードをいくつか持っています - 私はいくつかのモジュールでMono指令を持っています。私はこれがデバッグより良い例だと思う。

+0

コードの処理が異なる場合は、実行時にMonoで実行されているかどうかを確認し、それに応じて動作を変更する必要があります。そうすれば、1つのバイナリをすべてのプラットフォームに引き渡すことができます。 Monoでの実行は、Linuxでの実行を意味しないことに注意してください( '(Type.GetType(" System.MonoType ")!= null){...}'は、Monoランタイムで実行しているかどうかをテストするための推奨方法です。 Monoは、WindowsやOS Xのような他のプラットフォームでも利用できます)。しかし、あなたが実行しているランタイムをテストするのは悪い考えです。 Monoバグを回避する場合は、バグ自体が存在するかどうかをテストします。 – cdhowie

8

一般に、オプションの/条件付きコンパイルシンボルは、ビルドスクリプトによって提供される。 非常にのデバッグコードを除いて、#defineと表示されることは非常にまれです。変数を使用しています。私はしばしば、さまざまなランタイム(モノラル、cf、シルバーライトなど)で実行する必要のあるコードを処理するためにこのような条件を使用します。変数は、間違ったプラットフォーム(タイプ/メソッドが見つからないなど)に対してをコンパイルできないため、十分ではありません。

ここに示した例では、私はたぶんDebug.WriteLineを使用していました。 [Conditional("DEBUG")]で装飾されているため、buildでDEBUGが定義されていないと、すべての呼び出しは自動的に削除されます。

4

プロジェクトでプリプロセッサディレクティブを使用した例を挙げたいと思います。

私のプログラムは、ディスク上に多数の中間ファイルを作成します。 #DEBUGディレクティブを使用して、プロジェクトがリリースモードの場合にのみそれらのファイルを削除します。そうしないと、それらの中間ファイルを表示して内部で何が起きているかを判断できるようになります。

私のアプリがプロダクションサーバーで動作しているときに、プロジェクトがリリースモードでビルドされるため、処理が完了した後でそれらのファイルが削除されます。

#if (DEBUG==false) 
    deleteTempFiles() 
#endif 
+3

私は通常、#f!DEBUGと同じことを知っていますが、少しスリムです。 –

+0

@Neil、あなたのやり方も正しいですが、DEBUG = Falseが好きです。 – Shekhar

+0

私は、デバッグ時に決して得られない副作用があるかもしれないので、デバッグ設定でプロダクションコードを無効にしないことを強くお勧めします(はい、私たちは人生を知っていますか? )。あなたの例では、私はそれ以外の方法でそれをやります:DEBUGが設定されている場合は、他の場所で検査のために一時ファイルをコピーしてからclobberingしてください。物事を模倣しなければならない状況があることは認めていますが(取引サービスなど) – ofi

16

実際には、インライン#ifステートメントの代わりに条件付き属性を使用することをお勧めします。

[Conditional("DEBUG")] 
private void DeleteTempProcessFiles() 
{ 
} 

だけでなく、あなたのコード内の#if、#elseのを持って終了していないので、読むために、このクリーンで簡単です。このスタイルは、通常のコード編集やロジックフローのエラーのいずれかで、エラーの発生が少なくなります。

+1

私はこのスタイルを知らなかった。投稿していただきありがとうございます。 – Shekhar

+0

このメソッドは、条件が満たされているかどうかにかかわらず常に出力されることに注意してください。この属性は、このメソッドへの*呼び出しが送出されるかどうかにのみ影響します。これにより、ライブラリ内にメソッドを定義し、それに '[Conditional(" DEBUG ")]'を与えることができ、これはこのライブラリに対するコンパイルに影響します。 – cdhowie

+0

優れている、これ以上の情報もありますhttp://stackoverflow.com/q/3788605/932917 – mstaffeld

1

私は多くのことに使ってきました。デバッグビルドでのみ必要なデバッグメッセージ。一時ファイルをクリーンアップする。診断機能またはアクションを含む。

関連する問題