実際は、Visual Basic 2005 なんだけど、C# でも同じ、まぁ、実は C 言語でも同じ。
「マジックナンバーを使ってはいけません」というのを小さい頃(プログラミングを始めたばかりの頃ってこと)に教えられた人は、コードの中に即値を入れないようにします。だから、次のように書く…って、書くなぁッ!!!
const int ZERO = 0; const int TEN = 10; for ( int i = ZERO; i < TEN; i++ ) { // 何かの処理 }
その…なんというか、顎が外れた。言葉が出ない。
これの応用編(?)として、こんな風なコードもあった…あるなぁッ!!!
public class CONSTS { public const int ZERO = 0; public const int TEN = 10; } ... for ( int i = CONSTS.ZERO; i < CONSTS.TEN; i++ ) { // 何かの処理 }
ええっ、思いっきり応用していますね。応用です。鷹揚に構えないと(ぜはぜは)。
で、この手のものをどう書くのですか?と聞かれると、C言語だとこう書きます(実はC#だと悩ましかったり)。
#define MAX 10; ... for ( int i=0; i<MAX; i++ ) { ... }
「MAX」のところは最大値を示す意味のある言葉を入れるわけで、望ましくないのは「LOOPMAX」とか「COUNTMAX」とかですね。そうなる位であれば「MAX」のほうが潔い。
どうせならば「MAX_TABLES」とか「TABLE_COUNTS」な感じです。
さて、同じようなものをC#で書くと、
const int MAX = 10; ... for ( int i=0; i<MAX; i++ ) { ... }
という感じになりますが、ちょっと違う。この MAX という定義は、C 言語の場合は、関数(メソッド)の外に書くことができるけど、C# や VB の場合は、メソッドの中になってしまう。なので、オブジェクト指向のメリットを活かせば、
class A { const int MAX = 10; public method() { ... for ( int i=0; i<MAX; i++ ) { ... } } }
な風に、クラス内の private フィールドにするのが適しているかと。
実は、更に悩ましいことに、この MAX ってのは、共通で使うことが多いので、B クラスでも C クラスでも使うってことになると、
public class CONSTS { public const MAX = 10; }
なんていう CONSTS クラスを作っておいて、
class A { public method() { ... for ( int i=0; i<CONSTS.MAX; i++ ) { ... } } } class B { public method() { ... for ( int i=0; i<CONSTS.MAX; i++ ) { ... } } }
のようにすれば良いのだが、実はこれは隠蔽化を崩している。
新しく D クラスを作った時に、CONSTS.MAX というのが別の意味で使いたい場合に名前が重複してしまう。実務的には、アセンブリを変えるとか、定義名を別にするとかいう方法もあるのですが、実はインターフェースという感覚で
public class CONSTS { public const int MAX = 10; } public class A : CONSTS { public void method() { for ( int i=0; i<MAX; i++ ) { ... } } }
とするのが妥当かと思うのですが、.NET のクラスでは多重継承ができないので、CONSTS を複数作って継承させるってことができない。
なので、実務的なところでは、
public class TABLE_CONSTS { public const int MAX = 10; } public class PEOPLE_CONSTS { public const int MAX = 100; } public class A { public void method() { for ( int i=0; i<TABLE_CONSTS.MAX; i++ ) { ... } } }
な風に、CONSTS クラスをあらかじめ分類しておいて、名前空間風に使ってみる、っていうのが普通です…というか、今回はそうしました。
まぁ、CONSTS クラスが多くなるとちょっと…何が何やら分からなくなりますがね。
と・も・か・くッ!!! ONE, TWO THREE のような定義はやめておくなまし。
実は、自動生成をするときに名前を付けるのが面倒くさくて、const int KEY_1 = 1 という書き方をしたのだよね…これがいけなかったな。
const int KEY_JAPAN = “1”
const string NAME_JAPAN = “日本”
のようにするべきだった、と反省。
public class CONSTS {
public const MAX = 10;
}
static抜けてませんか?
これはこれで合っているんすよ。C# では const を付けると自動的に static と同じ扱いになるので、むしろ static を付けるとコンパイルエラーで通らないという現象になります。
あえて static をつけたい場合は static readonly で。