全く変化しない値、つまり定数を、異なる場所で何度も使いたいときC言語では、
#define PI 3.14159
と記述します。では、C#ではどのように記述するのでしょうか。C#では、const というキーワードを使用します。
static class Constants { public const double Pi = 3.14159; }
const を付けて宣言された定数は、宣言文中における初期化時にのみ値を代入できます。 定数というくらいですから、当然、 その他の場所で値を書き換えることは出来ません。この定数を使用するには、
class Program { static void Main() { double radius = 5.3; double area = Constants.Pi * (radius * radius); } }
とします。
const 以外に、もう1つ定数のようなものを実現する方法があります。 readonly というキーワードを用いて、読取り専用(read only)の変数を定義できます。
class SampleClass { public int x; // Initialize a readonly field public readonly int y = 25; public readonly int z; public SampleClass(int p1, int p2, int p3) { x = p1; y = p2; z = p3; } }
定数を設定して使用するには、
class Program { static void Main() { SampleClass p1 = new SampleClass(11, 21, 32); // 出力 p1: x=11, y=21, z=32 Console.WriteLine("p1: x={0}, y={1}, z={2}", p1.x, p1.y, p1.z); } }
とします。上の例で、次のようにステートメントを使用すると,
p2.y = 66; // Error
コンパイル エラー メッセージ「The left-hand side of an assignment must be an l-value」が表示されます。これは、定数に値を代入しようとしたときのエラーと同じです。const との違いは以下のようになります。
const | readonly |
---|---|
ローカル変数にも使える | クラスのメンバー変数のみ |
常に静的変数と同じ扱い | static の有無を変えられる |
宣言時にのみ初期化可能 | コンストラクタ内で値を書き換え可能 |
コンパイル結果はリテラルと同等 | コンパイル結果は変数と同等 |
インスタンスを new で生成するようなものには使えない | new 可能 |
クラス設計するときの、定数の定義のための設計方針について、次に示します。
定数の定義は、C言語では、ヘッダファイルにまとめて定義するのが一般的であるが、C#では、定数クラス(定数定義クラス)に集約するのが一般的である。 通常、定数クラスの利用者となるプログラマが必要とする定数は、一つないし数個に限られる。このため、C#でクラス設計を行う場合、定数クラスは、機能や目的ごとに、適切なサイズになるように分割して、見通しのよいクラスとするのが正しい。 また、C# にはグローバル変数という概念はないが、static を使うことで、プログラムのどこからでもアクセスできる。グローバル変数で値を共有するというのは、モジュールの結合度が高く、良い設計とはいえない。複数のクラスで使うデータは、できる限りグローバルなもので渡すのではなく、クラスからクラスへ、プロパティやメソッドを経由して渡す設計を行う。