如何实现抽象基类的相等性?

时间:2013-09-28 04:03:06

标签: c# abstract-class iequatable

我正在关注MSDN guidance for value equality,我发现了一个文档没有涵盖的案例,基类的等式。

一点背景:

我正在制作麻将游戏(4人,不匹配),我正在努力定义瓷砖。瓷砖可以分成两组:套装,有一个与它们相关的编号(可以按顺序放在一起,如2-3-4)和荣誉瓷砖,没有编号。

这是我到目前为止所拥有的:

public enum MahjongSuitType
{
    Bamboo = 1,
    Character,
    Dot
}

public enum MahjongSuitNumber
{
    One = 1,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine
}

public enum MahjongHonorType
{
    GreenDragon = 1,
    RedDragon,
    WhiteDragon,
    EastWind,
    SouthWind,
    WestWind,
    NorthWind
}

public abstract class MahjongTile
{

}

public class MahjongSuitTile : MahjongTile, IEquatable<MahjongTile>
{
    public MahjongSuitType SuitType { get; private set; }
    public MahjongSuitNumber SuitNumber { get; private set; }
    public bool IsRedBonus { get; private set; }  //this has no bearing on equality

    public MahjongSuitTile(MahjongSuitType suitType, 
                           MahjongSuitNumber suitNumber, 
                           bool isRedBonus = false)
    {
        this.SuitType = suitType;
        this.SuitNumber = suitNumber;
        this.IsRedBonus = isRedBonus;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as MahjongTile);
    }

    public bool Equals(MahjongTile other)
    {
        if (Object.ReferenceEquals(other, null))
            return false;
        if (Object.ReferenceEquals(other, this))
            return true;

        MahjongSuitTile otherSuitTile = other as MahjongSuitTile;
        if (Object.ReferenceEquals(otherSuitTile, null))
            return false;

        return (this.SuitType == otherSuitTile.SuitType) && 
               (this.SuitNumber == otherSuitTile.SuitNumber);
    }

    public override int GetHashCode()
    {
        return this.SuitType.GetHashCode() ^ this.SuitNumber.GetHashCode();
    }

}

public class MahjongHonorTile : MahjongTile, IEquatable<MahjongTile>
{
    public MahjongHonorType HonorType { get; private set; }

    public MahjongHonorTile(MahjongHonorType honorType)
    {
        this.HonorType = HonorType;
    }

    public override bool Equals(object obj)
    {
        return this.Equals(obj as MahjongTile);
    }

    public bool Equals(MahjongTile other)
    {
        if (Object.ReferenceEquals(other, null))
            return false;
        if (Object.ReferenceEquals(other, this))
            return true;

        MahjongHonorTile otherHonorTile = other as MahjongHonorTile;
        if (Object.ReferenceEquals(otherHonorTile, null))
            return false;

        return this.HonorType == otherHonorTile.HonorType;
    }

    public override int GetHashCode()
    {
        return this.HonorType.GetHashCode();
    }
}

对于大多数代码,我想通过基类引用tile,如:

List<MahjongTile> hand = new List<MahjongTile>() { ... };

HashSet<MahjongTile> dragonTiles = new HashSet()
{
    new MahjongHonorTile(MahjongHonorType.GreenDragon),
    new MahjongHonorTile(MahjongHonorType.RedDragon),
    new MahjongHonorTile(MahjongHonorType.WhiteDragon)
}

IEnumerable<MahjongTile> dragonTilesInHand = hand.Where(t => dragonTiles.Contains(t));

我的问题:我应该如何在MahjongTile基类中定义相等性?

1 个答案:

答案 0 :(得分:0)

由于Object.Equals是虚拟的,因此子类实现会覆盖该方法。不需要进一步的代码。