C# 元组上的Reasons Equals()可能返回false
我有一些代码想要使用元组作为字典的键,但是我在正确识别键时遇到了问题C# 元组上的Reasons Equals()可能返回false,c#,C#,我有一些代码想要使用元组作为字典的键,但是我在正确识别键时遇到了问题 Dictionary<Tuple<string, MyClass>, MyClass> Map = new Dictionary<Tuple<string, MyClass>, MyClass> { { Tuple.Create(s1, new MyClass { value = v1 }), new MyClass { value = r1 } } } Tuple<
Dictionary<Tuple<string, MyClass>, MyClass> Map = new Dictionary<Tuple<string, MyClass>, MyClass>
{
{ Tuple.Create(s1, new MyClass { value = v1 }), new MyClass { value = r1 } }
}
Tuple<string, MyClass> key = Tuple.Create(s, o);
foreach (Tuple<string, MyClass> t in Map.Keys)
{
if (t.GetType() == key.GetType()
&& t.Item1.Equals(key.Item1) && t.Item2.Equals(key.Item2)
&& t.Item1.GetHashCode() == key.Item1.GetHashCode() && t.Item2.GetHashCode() == key.Item2.GetHashCode())
{
bool test2 = t.Equals(key); // False?
bool test3 = t.GetHashCode() == key.GetHashCode(); // True
}
}
t和key都是System.Tuple这是平等所必需的:
t.Item2.Equals(key.Item2)
所以这取决于T。如果T是值类型,那么如果值相等,则返回true
如果T是引用类型,则只有当两个Item2引用同一实例,或者T重写了equals`以便不同的实例可以相等时,才会返回true
在此之前,您正在检查T的两个实例之间的==。这可能是多余的,但由于同样的原因,它也将失败。除非您还重写==运算符,否则它将检查引用类型是否相等
我首先删除==检查-只使用Equals-然后确保您可以期望Equals在您期望它返回true时返回true。这要么通过确保T覆盖等于给定您期望的行为,要么通过确保两者都是相同的实例。什么是T?因为这很可能是导致它错误的原因。如果T是引用类型,那么引用类型最有可能是比较引用,而不是比较成员,在这种情况下,它将返回false,除非T是完全相同的实例。如果我们可以复制它,那么会更容易提供帮助。。。你能提供一个吗?如果T是一个类,两个具有相同属性的实例不等于返回false,除非你的类型T适当地覆盖了object.Equals。投票关闭也很难,因为提供的代码不足以重现问题。@IanRingrose该代码不足以重现问题。唯一看起来不必要的代码行是,实际上只需要填充字典的一个值,而不是几个值。代码的其余部分都是必需的,但仍然不够。为了让代码到达代码t.Equalskey行,那么t.Item2.Equalskey.Item2必须已经返回true,所以我们知道它是true。看起来,当我实现了在if语句中调用的方法t.Equals时,我忽略了让它覆盖object.Equals,在比较元组类型对象时调用它^^ ^°