C# 为什么两个空列表不相等?
我以为对两个空列表调用Equals()会返回true,但事实并非如此。有人能解释一下原因吗C# 为什么两个空列表不相等?,c#,C#,我以为对两个空列表调用Equals()会返回true,但事实并非如此。有人能解释一下原因吗 var lst = new List<Whatever>(); var lst2 = new List<Whatever>(); if(!lst.Equals(lst2)) throw new Exception("seriously?"); // always thrown var lst=newlist(); var lst2=新列表(); 如果(!lst.等于(ls
var lst = new List<Whatever>();
var lst2 = new List<Whatever>();
if(!lst.Equals(lst2))
throw new Exception("seriously?"); // always thrown
var lst=newlist();
var lst2=新列表();
如果(!lst.等于(lst2))
抛出新异常(“严重?”);//总是扔
等于
这里比较两个列表的引用,这两个列表可能不同,因为它们是单独的列表,这就是为什么在这种情况下总是错误的原因 因为它比较的是对象标识,而不是列表的内容。它们是两个独立的对象
请参见C#常见问题解答。对象文档(MSDN文档):
Equals的默认实现支持引用类型的引用相等,以及值类型的位相等。引用相等是指被比较的对象引用引用同一对象。按位相等意味着被比较的对象具有相同的二进制表示
列表文档(MSDN文档):
确定指定的对象是否等于当前对象。(从对象继承。)
您有两个不同的对象(新的两倍…),因此不存在相同的对象。因为正在检查引用-lst
和lst2
是不同的对象。(请注意,Equals继承自对象
,而不是在列表
中实现)
你在找林克。即使在使用
SequenceEquals
时,也不要期望它能与非空列表上的任何类一起工作(除非它是一个结构)。您可能需要实现一个,并使用。列表。Equals()
将比较两个列表的引用,如果它们相等,则返回true。如果要比较两个列表的元素,请从文档中看到,使用List.SequenceEquals()
。列表上的Equals是从Object继承的方法,这意味着它会检查列表是否是相同的对象。由于您创建了两个对象,它们将不相同。当您将两个列表相互比较时,equals方法将不会比较该列表中的项目。它只会将列表对象与其他列表对象进行比较。它们有自己的“标识”等于列表的实现是从对象
继承的:
Equals的默认实现支持引用类型的引用相等
换句话说,由于这是两个不同的列表,它们具有不同的引用,因此Equals
返回false
它们是分配在内存中某处的两个不同列表(使用新关键字)。因此,他们不能平等。如果您想要这样的功能,您应该构建自己的对象,从列表继承并覆盖C#和.Net中的Equals函数,您有引用类型和值类型
值类型表示值<代码>整数
,双精度
,日期时间
等等
比较值类型时,会比较其实际值,因此:
int a = 10;
int b = 10;
if( a == b )
{
// this will fire
}
请注意,每个变量都引用一个新副本,因此:
int c = a;
c = c+5;
if( a == c )
{
// this won't, because a==10 and c==15
}
引用类型是传递给用户用来执行操作的对象。可以有多个变量引用同一对象,因此:
var a = new List<Whatever>();
var b = new List<Whatever>();
if( a == b )
{
// this won't fire, a and be are separate objects
}
var c = a;
c.Add(new Whatever());
if( a == c )
{
// this will, a and c are the same object.
a[0]; // holds the value added to c
}
var a=新列表();
var b=新列表();
如果(a==b)
{
//这不会开火,a和be是分开的对象
}
var c=a;
c、 添加(新内容());
如果(a==c)
{
//这将表明,a和c是同一个对象。
a[0];//保存添加到c的值
}
最后,引用类型的一些特殊情况的行为类似于值类型,例如string
两个不同的东西不可能是相同的,即使这些东西具有相同的项(或者都是空的)
你不需要擅长编程就能理解这一点;)假设你有一个这个和那个,那么这个和那个里面是什么并不重要。重要的是,这个不是那个或者那个不是这个。这就是你在那里检查的等于谢谢。对于这样的情况,如果没有其他内容,我觉得集合不重写Equals是愚蠢的。实际上,我认为两个包含相同对象、顺序相同的列表也是相等的。@VietNorm-这对于两个值类型列表可能有意义,但如果它们是更复杂的引用类型呢?Net中的大多数引用类型不会覆盖Equals
,因为它会产生非常混乱的行为。例如,如果你有一本字典
?如果List.Equals
被覆盖,.Net如何为该类构建基于哈希的查找。@Keith-我不理解你的问题。如果列表将覆盖Equals(),因此其返回取决于列表的内容,那么它将以类似的方式覆盖GetHashCode(),显然。@除非您知道列表的类型-List,否则这将非常困难。GetHashCode()
需要知道T
是什么。你不能只检查列表的长度,你需要为列表中的每个项目创建一个散列,并以一种不会相互抵消的方式将它们组合起来。解释为什么否决投票会很好,所以我知道如何改进。我也不理解否决投票。列表不覆盖Equals()这一事实是所有正确答案的本质。谢谢。好吧,也许是因为我的英语,但对我来说,两件事仍然是不平等的。这就是为什么他得到了例外。但如果你认为这和那是相同的参考…好的:)但我们需要一个例子。谢谢你,我很清楚发生了什么,我只是觉得这一点都不直观。在问了这个问题之后,我用Java做了同样的尝试,Java的Equals()的行为我觉得很直观——如果列表为空,它会返回true