126

これについて同僚と友好的な議論をしています。私たちはこれについていくつかの考えを持っていますが、SOの群衆はこれについてどう思っているのでしょうか?

4

13 に答える 13

83

一部の C# アーキテクトの不適切な判断だと思います。ローカル変数の readonly 修飾子は、プログラムの正確性を維持するのに役立ち (アサートと同様)、コンパイラがコードを最適化するのに役立つ可能性があります (少なくとも他の言語の場合)。現在 C# で許可されていないという事実は、C# の「機能」の一部が作成者の個人的なコーディング スタイルの強制にすぎないという別の議論です。

于 2011-04-29T10:51:26.377 に答える
32

Jaredの答えに対処すると、おそらくコンパイル時の機能である必要があります-コンパイラは、最初の宣言(割り当てを含める必要がある)の後に変数への書き込みを禁止します.

これに価値を見出せますか?可能性はありますが、正直なところ、多くはありません。変数がメソッドの他の場所に割り当てられるかどうかを簡単に判断できない場合は、メソッドが長すぎます。

価値のあることとして、Javaにはこの機能(final修飾子を使用)があり、匿名の内部クラスによって変数をキャプチャできるようにするために使用する必要がある場合と、それがどこにあるかを除いて、Javaが使用されることはほとんどありませ。使用すると、有用な情報ではなく、雑然とした印象を与えます。

于 2009-01-14T17:25:08.277 に答える
18

c#言語デザイナーの見落としです。F# には val キーワードがあり、CLR に基づいています。C# が同じ言語機能を持つことができない理由はありません。

于 2017-08-04T23:13:53.303 に答える
13

理由の 1 つは、読み取り専用ローカルに対する CLR サポートがないことです。読み取り専用は、CLR/CLI initonly オペコードに変換されます。このフラグはフィールドにのみ適用でき、ローカルには意味がありません。実際、それをローカルに適用すると、検証不能なコードが生成される可能性があります。

これは、C# がこれを実行できなかったという意味ではありません。しかし、それは同じ言語構造に 2 つの異なる意味を与えることになります。ローカル用のバージョンには、CLR に相当するマッピングはありません。

于 2009-01-14T17:07:41.400 に答える
7

私はその同僚で、友好的ではありませんでした!(冗談だ)

短いメソッドを書く方が良いので、私はこの機能を排除しません。難しいからといってスレッドを使うべきではないと言っているようなものです。私にナイフを渡して、自分を切らないように責任を負わせてください。

個人的には、混乱を避けるために、"inv" (不変) や "rvar" のような別の "var" タイプのキーワードが必要でした。私は最近 F# を勉強していて、不変であることが魅力的だと感じています。

Javaにこれがあるとは知りませんでした。

于 2009-01-14T17:59:43.230 に答える
5

ローカルのconst変数と同じように、ローカルの読み取り専用変数が必要です。ただし、他のトピックよりも優先度は低くなります。 おそらく、その優先順位は、C#設計者が(まだ!)この機能を実装しないのと同じ理由です。ただし、将来のバージョンでローカル読み取り専用変数をサポートするのは簡単(および下位互換性)である必要があります。

于 2012-04-30T13:20:19.847 に答える
1

読み取り専用は、インスタンス変数を設定できる唯一の場所がコンストラクター内にあることを意味します。変数をローカルで宣言する場合、インスタンスはなく (スコープ内にあるだけです)、コンストラクターによって変更することはできません。

于 2009-01-14T17:01:27.683 に答える
0

私は知っています、これはあなたの質問に対する理由には答えません。とにかく、この質問を読んでいる人は、それにもかかわらず、以下のコードを高く評価するかもしれません.

一度だけ設定する必要があるローカル変数をオーバーライドするときに自分自身を撃つことに本当に関心があり、それをよりグローバルにアクセス可能な変数にしたくない場合は、次のようにすることができます。

    public class ReadOnly<T>
    {
        public T Value { get; private set; }

        public ReadOnly(T pValue)
        {
            Value = pValue;
        }

        public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
        {
            if (object.ReferenceEquals(pReadOnlyT, null))
            {
                return object.ReferenceEquals(pT, null);
            }
            return (pReadOnlyT.Value.Equals(pT));
        }

        public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
        {
            return !(pReadOnlyT == pT);
        }
    }

使用例:

        var rInt = new ReadOnly<int>(5);
        if (rInt == 5)
        {
            //Int is 5 indeed
        }
        var copyValueOfInt = rInt.Value;
        //rInt.Value = 6; //Doesn't compile, setter is private

それほどコードは少ないかもしれませんrvar rInt = 5が、動作します。

于 2015-09-03T12:24:59.320 に答える
-6

これは、読み取り専用変数を持つ関数が呼び出されない可能性があり、おそらくスコープ外になる可能性があるためだと思います。また、いつ必要になるのでしょうか?

于 2009-01-14T16:37:44.767 に答える