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将等于bwhena并且b两者都引用同一个List<T>实例。

编辑:所以我自己查看了规范。它说:

List 类声明了两个运算符,运算符 == 和运算符 !=,从而为将这些运算符应用于 List 实例的表达式赋予了新的含义。具体来说,运算符将两个 List 实例的相等定义为使用它们的 Equals 方法比较每个包含的对象。以下示例使用 == 运算符比较两个 List 实例。

老实说...我不知道他们在说什么,但这似乎不正确。据我在运行一些测试后所知,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 回答