我正在从java迁移到c#。我正在阅读Bill Wagner的书,Effective C#第二版。我目前在第1章第6项“理解许多不同的平等概念之间的关系”,其中第40-41-42页中有一个示例代码,它应该显示错误实现Equals如何导致错误,错误是我我无法重现,它看起来像样本中的错误。这是下面的代码
public class B : IEquatable<D>
{
public override bool Equals(object right)
{
//
if (object.ReferenceEquals(right, null))
return false;
// Check reference equality:
if (object.ReferenceEquals(this, right))
return true;
// Problems here, discussed below.
B rightAsB = right as B;
if (rightAsB == null)
return false;
return this.Equals(rightAsB);
}
#region IEquatable<B> Members
public bool Equals(B other)
{
// elided
return true;
}
#endregion
}
和D类继承自B
public class D : B,IEquatable<D>
{
// etc.
public override bool Equals(object right)
{
// check null:
if (object.ReferenceEquals(right, null))
return false;
if (object.ReferenceEquals(this, right))
return true;
// Problems here.
D rightAsD = right as D;
if (rightAsD == null)
return false;
if (base.Equals(rightAsD) == false)
return false;
return this.Equals(rightAsD);
}
#region IEquatable<D> Members
public bool Equals(D other)
{
// elided.
return true; // or false, based on test
}
#endregion
}
根据书中的以下代码
B baseObject = new B();
D derivedObject = new D();
// Comparison 1.
if (baseObject.Equals(derivedObject))
Console.WriteLine("Equals");
else
Console.WriteLine("Not Equal");
// Comparison 2.
if (derivedObject.Equals(baseObject))
Console.WriteLine("Equals");
else
Console.WriteLine("Not Equal");
“第二次比较将永远不会返回真实”,它确实如此。我的意思是因为D是B的子类,第二个比较将最终从B调用Equals方法返回true,这对我来说是完全合理的。我错过了什么吗?
答案 0 :(得分:2)
我怀疑比尔意味着,如果使用Equals(object)
调用D
中的重写 baseObject
方法,则由于此部分,它将返回false:< / p>
D rightAsD = right as D;
if (rightAsD == null)
return false;
鉴于baseObject
的值不是对D
实例的引用,rightAsD
应为null
,所以它'将返回false
。
为了证明这一点,只需将baseObject
和derivedObject
变量的类型更改为object
即可。 (不要将它们初始化的值更改为声明的类型。)或者,只需转换为object
:
if (derivedObject.Equals((object) baseObject))
所以这本书说实施有问题是正确的 - 只是样本没有完全证明它。
答案 1 :(得分:0)
这是由于as
运算符和继承。
假设您有两个类,A
和B
,B
来自A
。
A a = new A();
B b = new B();
A x = b as A; // x is b
B y = a as B; // y is null