全く変化しない値、つまり定数を、異なる場所で何度も使いたいとき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 を使うことで、プログラムのどこからでもアクセスできる。グローバル変数で値を共有するというのは、モジュールの結合度が高く、良い設計とはいえない。複数のクラスで使うデータは、できる限りグローバルなもので渡すのではなく、クラスからクラスへ、プロパティやメソッドを経由して渡す設計を行う。