3
public abstract class Comparer<T> : IComparer, IComparer<T>
    {
        static Comparer<T> defaultComparer;    

        public static Comparer<T> Default {
            get {
                Comparer<T> comparer = defaultComparer;
                if (comparer == null) {
                    comparer = CreateComparer();
                    defaultComparer = comparer;
                }
                return comparer;
            }
        }

まず、Default プロパティはスレッドセーフですか? 次のステートメントの効果は可能ではないでしょうか

comparer = CreateComparer(); 

スレッドを作成する以外のスレッドには表示されない可能性がありますか? では、複数の Comparer インスタンスが構築されるのでしょうか?

Microsoft がこれを行っているのは、複数のオブジェクトを作成するコストと同期のコストを削減するためですか?

第二に、なぜ defaultComparer が最初に比較変数に割り当てられ、その後スワップされるのでしょうか? なぜ Comparer は比較者 = defaultComparer なのですか?

4

2 に答える 2

1

はい。複数の比較子が実際に作成され、defaultComparer が複数回割り当てられます。問題ありません。すべて同じです。ガベージ コレクタは余分なものを処理します。また、CLR がオブジェクト参照に対して提供するアトミック代入の保証により、static が正しく読み取られないことが保証されます。

于 2011-03-16T23:47:33.950 に答える
0

はい、確かに比較子の複数のインスタンスが作成される可能性があります。Defaultプロパティがスレッドセーフかどうかを判断する前に、何を安全にしたいのかを定義する必要があります。単一のインスタンスのみを作成したい場合、それは確かにスレッドセーフではありません。ただし、いくつかのインスタンスが返される限り、複数のインスタンスを許可するという要件を緩和すると、確かにそれが行われます。

IComparerこの決定の背後にある理由の一部は、インスタンスがステートレスであるという事実に基づいていると言えます。つまり、呼び出し元の観点からは、呼び出し元がどのインスタンスを取得するかは問題ではありません。それらはすべて同じように見えて動作するからです。言い換えれば、単一のスレッドが読み取りDefaultを繰り返し、毎回異なるインスタンスを取得しても、実際には問題になりません。

于 2011-06-13T17:53:51.197 に答える