有效的c#第二版勘误表

时间:2013-01-02 21:55:03

标签: c# errata

我正在从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,这对我来说是完全合理的。我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

我怀疑比尔意味着,如果使用Equals(object)调用D中的重写 baseObject方法,则由于此部分,它将返回false:< / p>

D rightAsD = right as D;

if (rightAsD == null)
    return false;

鉴于baseObject的值不是D实例的引用,rightAsD应为null,所以它'将返回false

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

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

所以这本书说实施有问题是正确的 - 只是样本没有完全证明它。

答案 1 :(得分:0)

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

假设您有两个类,ABB来自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