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

本文关键字:基类 抽象 何实现 实现 | 更新日期: 2023-09-27 18:33:17

我遵循 MSDN 的值相等性指南,我发现了文档未涵盖的情况,即基类的相等性。

一点背景:

正在开发一个麻将游戏(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();
    }
}

对于大多数代码,我想通过基类引用磁贴,如下所示:

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基类中定义相等?

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

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

相关文章: