9

readonly参照は変更されず、そのプロパティのみであるため、参照型変数があります。修飾子を追加しようとするvolatileと、コンパイルされたものから、両方の修飾子を同じ変数に適用できないことが警告されました。しかし、プロパティを読み取るときにキャッシュの問題が発生したくないため、揮発性である必要があると思います。何か不足していますか?それともコンパイラが間違っていますか?

更新以下のコメントの 1 つでマーティンが述べたように: 参照型オブジェクトの場合、readonly 修飾子と volatile 修飾子の両方が参照にのみ適用され、オブジェクトのプロパティには適用されません。それは私が見逃していたものなので、コンパイラは正しいです。

class C
{
    readonly volatile string s;  // error CS0678: 'C.s': a field cannot be both volatile and readonly
}
4

3 に答える 3

16

readonlynorvolatile修飾子も浸透性ではありません。これらは、オブジェクトのプロパティではなく、参照自体に適用されます。

readonlyキーワードは、初期化後に変数を変更できないことを表明し、強制します。変数は、参照が格納されるメモリの小さなチャンクです。

このvolatileキーワードは、変数の内容が複数のスレッドによって変更される可能性があることをコンパイラーに通知します。これにより、コンパイラーは、同時アクセスで問題を引き起こす可能性のある最適化(変数の値をレジスターに読み取り、その値を複数の命令で使用するなど)を使用できなくなります。繰り返しますが、これは参照が保存されているメモリの小さなチャンクにのみ影響します。

このように適用すると、それらが実際に相互に排他的であることがわかります。何かが読み取り専用である場合(初期化または構築時に一度だけ書き込むことができます)、揮発性にすることもできません(複数のスレッドによっていつでも書き込むことができます)。


キャッシュの問題、IIRCに関する懸念については、コンパイラがプロパティ呼び出しの結果をキャッシュできるタイミングについてはかなり厳格なルールがあります。これメソッド呼び出しであり、その値をキャッシュして再度呼び出すことをスキップすることは、(コンパイラーの観点から)かなり重い最適化であることに注意してください。あまり気にする必要はないと思います。

于 2008-12-28T17:22:47.323 に答える
1

読み取り専用フィールドは、オブジェクトが最初に構築されたときにのみ書き込むことができます。したがって、フィールドは不変であり、おそらく変更できないため、CPU でキャッシュの問題は発生しません。

于 2008-12-28T17:02:36.257 に答える
0

参照自体はスレッドセーフかもしれませんが、そのプロパティはそうでないかもしれません。2 つのスレッドが、参照オブジェクトに含まれる List を同時に反復処理しようとするとどうなるか考えてみてください。

于 2008-12-28T17:08:46.337 に答える