[解決済み] なぜC#ではconstパラメータが許されないのですか?
質問
特にC++の開発者にとっては奇妙に見えるでしょう。C++では、パラメータを
const
としてマークしていました。これは、パラメータの状態がメソッドの中で変更されないことを保証するためです。他にもC++特有の理由があって、例えば
const ref
を渡すなど、C++特有の理由もあります。しかし、なぜC#ではメソッドパラメータとしてconstをマークできないのでしょうか?
なぜ、次のようにメソッドを宣言できないのでしょうか?
....
static void TestMethod1(const MyClass val)
{}
....
static void TestMethod2(const int val)
{}
....
どのように解決するのですか?
他の良い答えに加えて、C#にC言語スタイルの定数を入れない理由をもう一つ付け加えましょう。 あなたは言いました。
メソッド内でパラメータが変更されないことを確認するために、パラメータをconstとしてマークしています。
constが実際にそうしてくれるなら、それは素晴らしいことです。constはそれをしません。constは嘘です!
constは実際に使える保証を何一つしてくれない。constなものを受け取るメソッドがあるとします。コードの作者は2人います。 呼び出し側 を書いている人と 呼び出し側 . callee の作者はメソッドに const を取るようにしました。二人の作者はこのオブジェクトについて何が不変であると仮定できるでしょうか?
何もありません。呼び出し側はconstをキャストしてオブジェクトを変更することができるので、呼び出し側には 保証 したがって、呼び出し側は、const を受け取るメソッドを呼んでも実際には 変異しないという保証はありません。同様に、着呼側は、着呼側のアクションの間、オブジェクトの内容が変化しない と仮定することはできません。着呼側は、ある突然変異を起こすメソッドを non const alias に対して変異を起こすメソッドを呼び出すことができます。 を変更しました。 .
Cスタイルのconstは、オブジェクトが変更されないという保証はなく、したがって、壊れています。さて、Cはすでに弱い型システムを持っており、本当に必要であればdoubleをintに再変換するキャストを行うことができます。 しかし、C#は 良い この変数に文字列を格納する」と言ったときに、その変数が、その文字列を含んでいることを示す型システムです。 が実際に文字列への参照を含んでいるような型システムです。 (または null) への参照を含むというものです。C スタイルの "const" 修飾子は絶対に型システムに入れたくありません。 型システムが嘘であってはならないからです。 . 私たちが望むのは、型システムが 強い というように 正しく推論できる ができるようになります。
C言語におけるConstは ガイドライン これは基本的に、このものを変異させないように私を信頼してください、という意味です。それは 型システム の中にあるものです。 型システム であるべきです。 ファクト ではなく、推論可能なオブジェクトに関するであるべきです。 ガイドライン でなく、その使い方に関するガイドラインです。
誤解しないでください。C言語のconstが深く壊れているからといって、その概念全体が役に立たないというわけではありません。私が見たいのは、いくつかの実際に 正しい と 役に立つ この注釈は、人間とコンパイラーの両方がコードを理解するのに役立ち、ランタイムが自動パラレリゼーションやその他の高度な最適化などを行うのに使用することができるものです。
たとえば、コードの塊の周囲にボックス (box") を描いて、次のように記述することができたらと想像してください。 保証 このコードの塊は、このクラスのどのフィールドに対しても変異を行わないことを保証します」と、コンパイラがチェックできるような方法で言えるとしたらどうでしょう。あるいは、次のようなボックスを描きます。 純粋な メソッドはオブジェクトの内部状態を変化させますが、ボックスの外で観察できるような方法では変化させません" と書かれたボックスを描くこともできます。このようなオブジェクトは自動的に安全にマルチスレッド化することはできませんが を自動的にメモすることができます。 . コードに付けることのできる興味深い注釈の数々は、豊富な最適化と深い理解を可能にしてくれます。 弱いCスタイルのconstアノテーションよりもずっと良いことができます。
ただし、強調したいのは、これはあくまで 推測 . この種の機能を C# の将来の仮想的なバージョンに搭載する確固とした計画はなく、もしあるとすれば、それは私たちが一方的に発表しているわけではありません。この機能はぜひとも実現したいものであり、今後マルチコア コンピューティングが重視されるようになれば必要になるかもしれませんが、C# の特定の機能または将来の方向性を予測または保証するものと解釈されるべきではありません。
さて、単にパラメータであるローカル変数に、"このパラメータの値はメソッドを通して変化しない"というアノテーションが欲しいだけなら、確かに、それは簡単にできるでしょう。ローカル変数とパラメータは一度だけ初期化され、メソッドの中で変更するとコンパイル時にエラーになるように、"readonly" をサポートすればよいのです。using"ステートメントで宣言された変数はすでにそのようなローカルです。すべてのローカルとパラメータにオプションのアノテーションを追加して、それらを "using"変数のように動作させることができます。これはあまり優先度の高い機能ではなかったので、これまで実装されたことはありません。
関連
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み】「namespace x already contains a definition for x」エラーの修正方法は?VS2010にコンバートした後に発生しました。
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] EqualsメソッドがオーバーライドされたときにGetHashCodeをオーバーライドすることが重要な理由は何ですか?
-
[解決済み] C#のconstとreadonlyの違いは何ですか?
-
[解決済み] C#でHashtableよりDictionaryが好まれる理由とは?
-
[解決済み] Static readonly」対「const」。
-
[解決済み] Java 8のインターフェイスメソッドで "final "が使えないのはなぜですか?
-
[解決済み】ビットシフト(bit-shift)演算子とは、どのようなもので、どのように機能するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】コンパイルエラー「未割り当てのローカル変数を使用しています」が発生したのはなぜですか?
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】HRESULTからの例外:0x800A03ECエラー
-
[解決済み】WSACancelBlockingCallの例外について
-
[解決済み】エラー「必要なフォーマルパラメータに対応する引数が与えられていない」を解決する?
-
[解決済み】IntPtrとは一体何なのか?
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み] C#のConst関数パラメータ [重複]について