6654


題名通り、const と static read only
の違いと使い分けについて下記の理解をもっています。もし、間違っていたり、アドバイスをいただける点がありましたら、是非お願いします。

MSDNのリファレンス：  
[readonly (C# リファレンス)](https://msdn.microsoft.com/ja-jp/library/acdd6hb7.aspx)

[const (C# リファレンス)](https://msdn.microsoft.com/ja-jp/library/e6w8fe1b.aspx)

![画像の説明をここに入力](https://i.stack.imgur.com/21q8C.png)


CC BY-SA 3.0
2015-02-17T23:02:18.547
6653
2015-02-23T09:21:38.080
2015-02-18T00:34:44.743
5987
question
c#
const と static read only の違いと使い分けについて


初期化の項はもにょります。よく読むとどちらも初期化が行われるにもかかわらず、なぜ必要・不必要に分かれるのか、その記述には何か意図があったりしますか？  
速度についてですが、.NETではJIT; Just-In-Time
Compileが行われます。ソースコード中で値の変わる変数に見えても実質的に値が変わらないようであれば定数としてコンパイルが行われます。ですのでstatic
readonlyが遅いというわけではありません。  
ディフォルト値は意図が読み取れませんでした。

その他として、constの場合、値型・文字列・nullが使えます。つまり文字列以外の参照型は使えません。static
readonlyにはこのような制限はありません。

あとマニアックな話としてstatic readonlyは実行時に初期化されます。この言葉の意味は、初期化前に参照すると別の値（nullや0）が読み出せます。

[code]

    class A {
        public static readonly int A2 = B.B2 + 1;
    }
    class B {
        public static readonly int B2 = A.A2 + 1;
    }
    
[/code]

もし先にAにアクセスするとA2の初期化が行われます。その際、B.B2を参照しますのでそこでBの初期化が行われます。B2の値を決定すべくA.A2を参照しますが未初期化ですのでA.A2は0が読み出されB.B2は1で確定します。引き続きA2の初期化が行われ、A2
= B.B2 + 1は2で確定します。

もちろんBを先にアクセスすると値は入れ替わります。  
これらが、初期化の項やディフォルト値に絡んでくるかもしれません。


CC BY-SA 3.0
2015-02-17T23:32:31.527
6654
2015-02-17T23:32:31.527
4236
6653
answer


「注意」の項目が気になったのでそこだけ。

>
> 別のアセンブリから定数を参照する場合、その値は、呼び出しのアセンブリへコピーされます。呼び出し元のアセンブリにて定数を変更しでも、呼び出し先の定数が更新されます。

アセンブリXで定義したconstをアセンブリYで参照するとき、Xでその値を変更すると、Yを再ビルドしないと変更後の値はYに反映されません。

[Eric
Lippertによれば](https://stackoverflow.com/a/9116587/3782011)、そもそもそのような状況はあってはならないもので、将来変更され得るような値をconst定義すべきではありません。円周率や金の原子に含まれる陽子の数のような、絶対不変の値のみがconst定義されるべきものである、と。  
(とはいえ、私としてはデフォルト引数などで使えるようにconst定義が必要な場合もある気はします。)


CC BY-SA 3.0
2015-02-18T02:53:57.993
6670
2015-02-18T02:53:57.993
2017-05-23T12:38:55.307
-1
4765
6653
answer


指摘されていない誤りがあるのでそこだけ。

表の _static readonly_ の _デフォルト値_ に

> インスタンスが作成されたときに評価される

とありますが、これは型が最初に参照されたタイミングが正しいです。この際コードの **上から順に**
staticフィールド初期化子(フィールド宣言と同時に値を記述すること=質問の _初期化_
)が評価され、その後staticコンストラクターを実行します。ですのでクラスを分けなくとも、

[code]

    class A
    {
        static int C = B + 1;
        static int B = 1;
    }
    
[/code]

と定義するだけでconstとは異なる結果となります。

あと最下行の _使用する場合_ にgetへの言及がありますが、プロパティと併用するならinternal constとpublic
staticプロパティという組み合わせが自然に感じます。


CC BY-SA 3.0
2015-02-18T13:03:58.377
6704
2015-02-18T13:03:58.377
5750
6653
answer


他の方も書いていますが、  
もう少しくだけて説明すると、const変数は自分が作ったアセンブリをクラスライブラリとして配布してしまうと、constの値を変えた場合は、それを使う側のアプリはリビルドしなければ反映されません。dll差し替えだけでは反映されないので注意。  
read onlyはリビルドしなくても反映されます。  
なのでconstは将来絶対に変わることのない値を定義するのに使うのが良いと思います。

対してreadonlyは実行速度はconstより遅く、switch文に使えないという主なデメリットがあります。


CC BY-SA 3.0
2015-02-23T09:21:38.080
6961
2015-02-23T09:21:38.080
3496
6653
answer