Hatena::ブログ(Diary)

しがないプログラマ の日記 RSSフィード Twitter

0000 | 00 |
2004 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 |
2011 | 01 | 03 | 05 | 06 | 07 | 08 | 09 | 11 |
2012 | 01 | 02 | 04 | 06 | 07 | 08 | 09 | 11 |
2013 | 01 | 03 |
2014 | 04 | 05 | 12 |
2015 | 03 | 11 |

2006年4月5日(水) この頃、雨が多くなってきましたね。

readonlyとconstの使い分け

(追記)

この記事は未だにgoogle経由でアクセスが多いようなので、結論をまとめておきます。経緯は以下のコメントを含めた本文を読んでいただければ分かるかと思います。

C#で定数を定義したい場合に、constが使える場合は常に使った方がいいです。つまり、対象となる値の型が値型ならばconstを、参照型ならばstatic readonlyを使うことになります。

普段、定数にしたい値はintやstringが多いと思いますので、大体の場合にconstが使えるはずです。

(追記終わり)


この頃、ずっとC#を使っているのですが readonlyと constをどう使い分けるのが良いのかがいまいち分かりません。そもそもJavaと同じ感覚で使おうとすると、Javaの finalとC#の readonlyがちょうど同じような宣言のため、constがあることに気が付きませんでした。

また、あるクラスで定数を定義しようとして

private static ??? int CONST_NUMBER = 1;

等と書きたい時に constが使えません。staticなフィールドには適用できないらしいです。readonlyやこの時にも使えるので、結局 readonlyしか使わないようになってしまいました。

constを使った方が良い or こういう場合はconstしか使えない、と言う状況はあるのでしょうか?MSDNを読むと「const フィールドコンパイル時定数であるのに対し、readonly フィールドは実行時定数として使用できます。」とありますが、実質的な違いはどのようなものがあるのでしょう?配列の長さなどに const定数を使っておけばコンパイル時に長さが最適化されたりするのかな?

うーん。。。

通りすがり通りすがり 2006/04/09 03:25 constはつまりコンパイル時定数=ILに値が「そのまま埋め込まれる」完全な定数です。なので、使用できる型が決まっています。言語的に言えばリテラルみたいなもので、newがいらず初期化コードがありません(みえません)。

また、明確な動作の違いとしては、参照時の動作です。コンパイル時に確定するのでコンパイラは実行時にそのメンバを参照させず、直接埋め込む動作になります。このため、例えばコンパイル時にあるアセンブリのconst定数を参照していて、後にその定数を書き換えた場合、それを参照しているアセンブリも再コンパイルしなければ値は更新されません(constを直接使った場合引っかかりにくいですが、enumもconstですのでこれが以外にはまります)。

後は以下のコードはreadonlyにすれば、コンパイルエラーで弾かれます。constはつまり他の静的要素にも使用できるわけです。

const string MESSAGE = ”const”;
//static readonly string MESSAGE = ”readonly”;
[Obsolete(MESSAGE)]
static void Foo() {
}

Horiuchi_HHoriuchi_H 2006/04/09 14:43 なるほどなるほど。詳しい説明ありがとうございます。
const=名前付きのリテラル相当と言う事なのですね。それと、enumの値もconst扱いなんですね。確かにreadonlyとの違いも分かるのですが、実際に使う時には相当速度を気にする場合以外は定数でもstaticなreadonlyを使っておけば良いのかなぁ?と思ってしまいます。
最後の例だけは、constでないとダメな例なのですね。

通りすがり通りすがり 2006/04/09 15:21 なんか「これや」って理由があったようなとひっかかってたんですがさっき思い出しました。switch文のcaseラベルです。あれはconstしか入れられません。組み込み型の定数値でswitch使うことは多いので致命的かなと。
どっちにしろconstのほうが適用可能範囲は広い(しかし柔軟性はない)ので出来るならconst、できないならreadonlyと私は使い分けてます。

Horiuchi_HHoriuchi_H 2006/04/09 18:07 ふむふむ。でも、switchに使いそうなのはenumかな、と思いますがどうなんでしょ?
enumは普通に使ってたので、readonlyな値はswitchのラベルには使えないことには気づきませんでした。なるほどー。ありがとうございます^^

valpvalp 2009/02/13 01:41 今更ですけど、constは実質的に、staticももれなく付いているも同然ですよね。だからstaticをわざわざ書くと冗長だとエラーにされます。とっくに分かっているかもしれませんが、ググると、割と上位に来るので、勝手ながら補足します。

Horiuchi_HHoriuchi_H 2009/02/13 07:54 コメントありがとうございますー。
この時はまだJava脳だったのでVMが最適化してくれれば、readonlyでもconstでも同じじゃん?とか思ってました。しかし、.NETのILなどを直接いじっていたら、定数とreadonlyは別の概念でそれぞれ必要なことが分かってきました。
その上で、「constにはstaticが付けれない」ではなくて「constだからstaticがそもそも不要」と理解できました。
補足ありがとうございます。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/Horiuchi_H/20060405/1144227687
リンク元
PV: 1176225