全く変化しない値、つまり定数を、異なる場所で何度も使いたいとき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の違い
const readonly
ローカル変数にも使える クラスのメンバー変数のみ
常に静的変数と同じ扱い static の有無を変えられる
宣言時にのみ初期化可能 コンストラクタ内で値を書き換え可能
コンパイル結果はリテラルと同等 コンパイル結果は変数と同等
インスタンスを new で生成するようなものには使えない new 可能


クラス設計するときの、定数の定義のための設計方針について、次に示します。
定数の定義は、C言語では、ヘッダファイルにまとめて定義するのが一般的であるが、C#では、定数クラス(定数定義クラス)に集約するのが一般的である。
通常、定数クラスの利用者となるプログラマが必要とする定数は、一つないし数個に限られる。このため、C#でクラス設計を行う場合、定数クラスは、機能や目的ごとに、適切なサイズになるように分割して、見通しのよいクラスとするのが正しい。
また、C# にはグローバル変数という概念はないが、static を使うことで、プログラムのどこからでもアクセスできる。グローバル変数で値を共有するというのは、モジュールの結合度が高く、良い設計とはいえない。複数のクラスで使うデータは、できる限りグローバルなもので渡すのではなく、クラスからクラスへ、プロパティやメソッドを経由して渡す設計を行う。