子类中的继承对等,如何与baseClass获得相同的结果?

时间:2019-05-07 20:39:14

标签: c#

我正在尝试为我的baseClass和subClasses写一个Equivalence函数。 “等价”是指我要检查比较实例的所有(或某些)属性是否相等/等效。

当我有一个基类列表时,我想检查一下列表中哪些元素具有相同的匹配项。

比方说,基类称为“ Item”。子类是“ WeaponItem”,“ ConsumableItem”,“ EquipableItem”,“ ArmorItem”等。(任何数量的具有任何继承深度的子类)。

如果我有一个项目列表,即使实例可以是任何子类,我也只能在项目类级别检查等效性。

我的问题是,基本级别的等效结果与特定级别的等效结果不同:

List<Item> itemList = new List<Item>();
WeaponItem weaponItem1 = new WeaponItem();
weaponItem1.strength = 1;
WeaponItem weaponItem2 = new WeaponItem();
weaponItem2.strength = 5;
WeaponItem weaponItem3 = new WeaponItem();
weaponItem3.strength = 5;
weaponItem1.IsEquivalent(weaponItem2);//returns false
weaponItem2.IsEquivalent(weaponItem3);//returns true
itemList.Add(weaponItem1);
itemList.Add(weaponItem2);
itemList[0].IsEquivalent(itemList[1]);//returns true

(itemList[0] as WeaponItem).IsEquivalent((WeaponItem)itemList[1]);//returns false

Item中的IsEquivalent函数仅检查一件事。 而WeaponItem中的IsEquivalent函数会检查WeaponItem类中的所有属性。

所以我的问题是,当我不能转换实际类型,因为它可能是Item的任何子类时,如何为List中的任何项目调用正确的IsEquivalent函数?

因此,在上面的示例代码中,我想以返回false的方式更改前一行,或者更改实现IsEquivalent函数的方式。

感谢您抽出宝贵的时间对此进行研究。

编辑:所以错误在于我实现IsEquivalence方法的方式,但我没有重写基本函数...我想我很累。 我假设如果我正在使用IEquatable(等于,==,!=,GetHash),则需要对IEquatable <'Item>使用一次,然后为每个子类覆盖这些函数。不需要也添加IEquatable <'WeaponItem>,或者我认为这是错误的吗?

1 个答案:

答案 0 :(得分:2)

您正在谈论的是使用面向对象编程的基本功能:polymorphism

使用多态性,在对象上调用IsEquivalent会调用在该对象的实际类中实现的版本,而不是在其所引用的基类中实现的版本。

所以,这是一个实现:

public abstract class Item {
    public virtual bool IsEquivalent(Item i2) {
        return true;
    }
}

public class WeaponItem : Item {
    public int strength;

    public override bool IsEquivalent(Item i2) {
        var ans = base.IsEquivalent(i2);
        if (i2 is WeaponItem w2)
            ans = ans && strength == w2.strength;
        return ans;
    }
}

注意:如果两种等效类型不同,或者SameType与SameType(例如Item与{ {1}}相同时,您将需要使用双调度多态性来捕获第一个类型,然后将等效性测试委托给第二个Item,以避免在每个WeaponItem中进行类型测试。如果您不介意性能下降,也可以使用WeaponItem进行两次调度。