3

我正在从 java 迁移到 c#。我正在阅读 Bill Wagner 的书,Effective C# second edition。我目前在第 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,这对我来说完全有意义。我错过了什么吗?

4

2 回答 2

2

我怀疑比尔的意思是,如果用调用重写 Equals(object)的方法,由于这一部分,它将返回 false:DbaseObject

D rightAsD = right as D;

if (rightAsD == null)
    return false;

鉴于 的值baseObject不是的实例的引用DrightAsD应该是null,所以它会返回false

为了证明这一点,只需将baseObjectderivedObject 变量的类型更改为object。(不要更改它们初始化的值,只更改声明的类型。)或者,只需转换为object

if (derivedObject.Equals((object) baseObject))

所以这本书说实施有问题是正确的——只是示例并没有完全证明它。

于 2013-01-02T22:00:01.023 回答
0

这是由于as运算符和继承。

假设您有 2 个类,A并且BB派生自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
于 2013-01-02T22:00:11.710 回答