2010-12-10 8 views
13

静的クラスで公開されている定数の値を変更して、アセンブリの古いコピーを新しくコンパイルしたバージョンに置き換えたとき、私は今や少し驚いています。驚いたことに、アセンブリを参照していた既存のプログラムが定数の新しい値を取得していないということでした。つまり、私は実行可能ファイルを再コンパイルしませんでしたが、むしろその1つのアセンブリを置き換えました。.NETでは、定数はJIT時ではなくコンパイル時に評価されるのはなぜですか?

私の実験の完全な説明は、私がこの動作により、非常に驚​​いているに認めるよHow constant is a constant?

です。私は何が起こっているのか理解していますが、私は理解していませんなぜ。コンパイル時ではなく、JIT時に定数を取得できないという特別な技術的な理由はありますか?それをすることで事態が壊れるケースはありますか?

+0

を、それは実際にそれは驚くべきことではないので、これは、あまりにも多くの書籍、ブログの記事で説明された動作です:) –

+0

@Lex:奇妙なことに、私は以前はそれについて議論したことはありません。私はまだ疑問に思っています。 –

+1

私はまだ使用しているアセンブリにそれを焼くことの利点が何であるか分かりません。 – CodesInChaos

答えて

30

定数は、定数とします。全日の場合定数は、piの値、または先頭原子のプロトンの数のようなものです。

定数が変更された場合、は実際には定数ではありませんでした;代わりにreadonlyフィールドを使用してください。決して変わらない定数の

使用定数フィールド:

また状態Frameworkの設計ガイドラインを参照してください。コンパイラはconstフィールドの値を呼び出しコードに直接書き込みます。したがって、互換性を損なうことなくconst値を変更することはできません。

本質的に、それに依存するすべてのものを再コンパイルせずに定数を変更すると、メソッドのシグネチャを変更することと同じくらい壊れてしまいます。コンパイラは、従属アセンブリをコンパイルするときに、参照されたアセンブリからのメタデータに関するあらゆる種類の前提を「奪い取る」。 に変更すると、単純に作業を続けることは期待できません。

+0

JITコンパイラは読み取り専用フィールドを評価し、ネイティブコードにコンパイルするときに定数として扱いますか?つまり、定数を使用する場合と読み取り専用フィールドを使用する場合のパフォーマンスに違いがありますか? –

+5

@ジム:分かりません。最初に、半ダース以上のJITコンパイラがあり、私はそれらのどれも専門家ではありません。次に、JITコンパイラは、デバッガが接続されているかどうかなど、実行時に発生するものに基づいて動作を変更することがよくあります。第3に、パフォーマンスを心配している場合は、両方の方法でコードを書いて実行し、違いを測定できるかどうかを確認します。差が小さすぎて測定できない場合は、最初は心配する必要はありません。 –

+7

PIが今や正確に3であると聞いた。 – ChaosPandion

1

「定数」を宣言する3つ目の方法もあります:public staticプロパティ。

public static string ConstString {get{return "First test";}} 

これは読み取り専用フィールドのバージョニングのセマンティクスを持っていますが、ジッタがゲッターをインライン化した場合には、JIT時の一定となります。また、constとは異なり、ユーザー定義型で使用できます。

各プロパティアクセスで新しいインスタンスを割り当てたくないので、値型と文字列には静的プロパティを使用することをお勧めしますが、ユーザー定義クラスには使用しないことをお勧めします。

私はこのような私の固定小数点タイプでこれを使用:

public struct FixedPoint 
{ 
    private int raw; 
    private const fracDigits=16; 

    private FixedPoint(int raw) 
    { 
    this.raw=raw; 
    } 

    public static FixedPoint Zero{get{return new FixedPoint();}} 
    public static FixedPoint One{get{return new FixedPoint(1<<fracDigits);}} 
    public static FixedPoint MaxValue{get{return new FixedPoint(int.MaxValue);}} 
} 
関連する問題