22

C#言語仕様バージョン4では、1.6.7.5演算子は演算子に関する情報ですList<T>==および!=List<T>しかし、 ?で定義されているそのような演算子が見つかりません。私は何かが足りないのですか?

1.6.7.5演算子のサンプルコード:

List<int> a = new List<int>();
a.Add(1);
a.Add(2);
List<int> b = new List<int>();
b.Add(1);
b.Add(2);
Console.WriteLine(a == b); // Outputs "True" => here I get False as well
b.Add(3);
Console.WriteLine(a == b); // Outputs "False"
4

2 に答える 2

22

List<T>オーバーロードしない参照型operator==です。したがって、デフォルトの参照等式セマンティクスを使用します。値のセマンティクスを提供するためにオーバーライドするという印象を受けているようですが、operator==そうではありません。 と両方が同じインスタンスを参照する場合aは等しくなります。babList<T>

編集:それで私は自分でスペックを見ました。それは言う:

Listクラスは、operator ==とoperator!=の2つの演算子を宣言しているため、これらの演算子をListインスタンスに適用する式に新しい意味を与えます。具体的には、演算子は、Equalsメソッドを使用して、含まれている各オブジェクトを比較するものとして、2つのListインスタンスの同等性を定義します。次の例では、==演算子を使用して2つのリストインスタンスを比較しています。

正直なところ...彼らが何について話しているのか私にはわかりませんが、これは正しくないようです。いくつかのテストを実行した後、私が知る限り、List<T>クラスは参照の等式を使用します。良い質問。

EDIT2:逆コンパイルさList<T>れた、ノーoperator==および/またはoperator!=オーバーロード。この場合、仕様は完全に正しくないようです。

于 2012-08-07T19:18:22.427 に答える
17

紛らわしいですが、仕様は確かに正しいです。この仕様では、List という名前のクラスが定義されています (名前の選択が不適切です)。

次の表は、拡張可能なオブジェクトのリストを実装する List というジェネリック クラスを示しています。このクラスには、最も一般的な種類の関数メンバーの例がいくつか含まれています。

このクラスは、セクション 1.6.7 の仕様で確認できます。Equals 演算子はオーバーロードされており、上記で説明した出力と一致します。おそらく、そのクラスにはより適切な名前を選択する必要がありました。

static bool Equals(List<T> a, List<T> b) {
    if (a == null) return b == null;
    if (b == null || a.count != b.count) return false;
    for (int i = 0; i < a.count; i++) {
        if (!object.Equals(a.items[i], b.items[i])) {
            return false;
        }
    }
  return true;
}
于 2012-08-07T19:37:30.110 に答える