他の良い答えに加えて、Cスタイルの定数をC#に入れない理由をもう1つ追加します。あなたが言った:
メソッドで状態が変更されないように、パラメーターをconstとしてマークします。
constが実際にそれを行った場合、それは素晴らしいことです。Constはそれを行いません。constは嘘です!
Constは、実際に使用できるという保証はありません。constを取るメソッドがあるとします。コード作成者は2つあります。発信者を作成する人と着信者を作成する人です。呼び出し先の作成者は、メソッドにconstをとらせました。2人の著者がオブジェクトについて不変であると仮定できるものは何ですか?
何もない。呼び出し先は自由にconstをキャストしてオブジェクトを変更できるため、呼び出し元は、constを取るメソッドを呼び出しても実際には変更されないという保証はありません。同様に、呼び出し先は、オブジェクトの内容が呼び出し先のアクションを通じて変化しないとは想定できません。呼び出し先は、constオブジェクトの非constエイリアスでいくつかの変更メソッドを呼び出すことができましたが、いわゆるconstオブジェクトが変更されました。
Cスタイルのconstは、オブジェクトが変更されないことを保証しないため、壊れます。現在、Cにはすでに弱い型システムがあり、本当に必要な場合は、doubleをintに再解釈してキャストできるため、constに関しても弱い型システムがあることは当然のことです。しかし、C#は適切な型システム、つまり「この変数に文字列が含まれている」と言うと、変数が文字列(またはnull)への参照を実際に含む型システムを持つように設計されています。型システムを嘘にしたくないので、Cスタイルの「const」修飾子を型システムに入れたくありません。コードについて正しく推論できるように、型システムを強くする必要があります。
CのConstはガイドラインです。それは基本的に「あなたが私にこれを変異させようとしないことを信頼できる」ことを意味します。それは型システムにあるべきではありません。型システムの内容は、その使用法のガイドラインではなく、推論できるオブジェクトに関する事実でなければなりません。
誤解しないでください。Cのconstが深く壊れているからといって、コンセプト全体が役に立たないというわけではありません。私が見たいのは、C#の「const」アノテーションの実際に正しくて便利な形式です。このアノテーションは、人間とコンパイラの両方がコードを理解するために使用でき、ランタイムは自動並列化やその他の高度な最適化。
たとえば、コードの塊の周りに「ボックスを描く」ことができ、コンパイラがチェックできる方法で「このコードの塊がこのクラスのどのフィールドに対しても変更を行わないことを保証する」と言うことができると想像してください。または、「この純粋なメソッドはオブジェクトの内部状態を変更しますが、ボックスの外側で観察できる方法では変更しない」というボックスを描画します。このようなオブジェクトは、安全に自動的にマルチスレッド化することはできませんが、自動的にメモ化できます。リッチな最適化とより深い理解を可能にする、あらゆる種類の興味深い注釈をコードに付けることができます。弱いCスタイルのconstアノテーションよりも優れた方法を実行できます。
ただし、これは単なる推測にすぎません。私たちは、このような機能を将来の仮想バージョンのC#に組み込む計画はありません。これは私が見たいものであり、今後マルチコアコンピューティングに重点を置く必要があるかもしれませんが、C#の特定の機能または将来の方向性の予測または保証であると解釈されるべきではありません。
ここで、必要なのは、「このパラメーターの値はメソッド全体で変更されない」というパラメーターであるローカル変数の単なる注釈である場合、それは簡単に行えます。一度初期化される「読み取り専用」のローカルとパラメーター、およびメソッドで変更するコンパイル時エラーをサポートできます。「using」ステートメントによって宣言された変数は、すでにそのようなローカルです。すべてのローカルとパラメーターにオプションの注釈を追加して、変数を「使用する」ように動作させることができます。これは非常に優先度の高い機能ではなかったため、実装されたことはありません。