複雑な条件の指定
#ifは、常にシンボル1個しか指定できないわけではない。より高度な指定の例をいくつか紹介しよう。
1: #define MY_SWITCH1
2: #undef MY_SWITCH2
3: using System;
4:
5: namespace ConsoleApplication1
6: {
7: class Class1
8: {
9: static void Main(string[] args)
10: {
11: #if true
12: Console.WriteLine("#if true");
13: #endif
14: #if false
15: Console.WriteLine("#if false");
16: #endif
17: #if MY_SWITCH1 || MY_SWITCH2
18: Console.WriteLine("MY_SWITCH1 or MY_SWITCH2 is ON");
19: #else
20: Console.WriteLine("MY_SWITCH1 or MY_SWITCH2 is OFF");
21: #endif
22: #if MY_SWITCH1 && MY_SWITCH2
23: Console.WriteLine("MY_SWITCH1 and MY_SWITCH2 is ON");
24: #else
25: Console.WriteLine("MY_SWITCH1 and MY_SWITCH2 is OFF");
26: #endif
27: }
28: }
29: } |
|
複雑な条件を使用したサンプル・プログラム6 |
#ifには「true」、「false」や複数の条件を記述することができる。 |
これを実行すると以下のようになる。
|
サンプル・プログラム6の実行結果 |
#ifの条件が成立した部分のみが実行されているのが分かる。
|
11行目と14行目の条件に記述された「true」と「false」は、それぞれ、「条件が常に成立する」「成立しない」ということを示す定数値である。条件が固定された#ifなど無意味と思われるかもしれないが、ソースを書いている途中で、条件が決まらない段階で#ifによる場合分けを書く場合もある。そういう場合に仮に書き込んでおく用途もある。
17行目と22行目は、複数のシンボルを参照した条件判断である。「||」と「&&」は、それぞれ、C#の演算子と同じ意味を持つ。「||」は、前後のシンボルのどちらかが定義されているとき、「&&」は前後のシンボルが両方とも定義されているときを意味する。このほかに、一致と不一致を判定する「==」と「!=」も使用できる。また、否定の「!」も使用できる。例えば、「#if MY_SYMBOL」ならシンボルが定義されているときだが、「#if !MY_SYMBOL」とすれば、シンボルが定義されていないとき、となる。
誤った使い方
ここは、C/C++プログラマ向けの情報である。C/C++にもプリプロセッサがあり、同じような名前を用いるが、必ずしも機能は同じではない。C/C++では正しいが、C#では正しくない例を以下に示す。
1: #define MY_SYMBOL1 123
2: #define MY_SYMBOL2(x) Console.WriteLine(x)
3: using System;
4:
5: #define MY_SYMBOL3
6:
7: #ifdef MY_SYMBOL4
8: #endif
9:
10: namespace ConsoleApplication2
11: {
12: class Class1
13: {
14: static void Main(string[] args)
15: {
16: Console.WriteLine("Not Executable");
17: }
18: }
19: } |
|
誤った使用法を示すサンプル・プログラム7 |
このプログラムはコンパイル・エラーとなる。C/C++のプリプロセッサと同じような名前を用いるが、必ずしも機能は同じではない。 |
まず1行目。C#では、シンボルは定義できるだけで、値を持たせることはできない。つまり、シンボルに“123”という文字列を関連づけることはできない。2行目のような引数も当然存在しない。5行目は一見正しいように見えるが、C#では、#defineや#undefは、コンパイラ本体が処理するすべてのコードの前に記述される必要がある。このソースでは、3行目のusingステートメントが最初のコードなので、それよりも前に記述しなければならない。7行目は、C/C++プログラマがうっかりミスをしそうな例だが、「#ifdef」はC#には存在せず、「#if」を使う。
複数条件を記述するための#elif
条件が増えると、#if-#else-#endifだけで記述すると込み入ってしまう場合がある。そういう場合のために「#elif」が用意されている。これは、#elseの機能と#ifの機能が合体したものである。以下はそれを用いた例である。
1: #define MY_SYMBOL2
2: using System;
3:
4: namespace ConsoleApplication8
5: {
6: class Class1
7: {
8: static void Main(string[] args)
9: {
10: #if MY_SYMBOL1
11: Console.WriteLine("MY_SYMBOL1");
12: #elif MY_SYMBOL2
13: Console.WriteLine("MY_SYMBOL2");
14: #elif MY_SYMBOL3
15: Console.WriteLine("MY_SYMBOL3");
16: #else
17: Console.WriteLine("no symbols");
18: #endif
19: }
20: }
21: } |
|
「#elif」を使用したサンプル・プログラム8 |
「#elif」を使用することにより、込み入った条件をすっきりと記述することができる。 |
これを実行すると以下のようになる。
|
サンプル・プログラム8の実行結果 |
4つあるWriteLine呼び出しのうち、“MY_SYMBOL2”の部分のみがコンパイルされる。
|
複数条件で#if-#else-#endifを使う場合、#ifを1回記述するごとに、それに対応する#endifを記述しなければならない。つまり、#ifで判定すべき条件が3個あれば、#endifも3個必要になる。しかし、#elifを使えば、上記のように、条件が3個でも#endifは1個しか記述しなくてよい。
Insider.NET 記事ランキング
本日
月間