【发布时间】:2018-01-17 09:18:41
【问题描述】:
我需要在一个列表中保留几个基类的孩子。通常不是问题,但由于涉及泛型,这让我很头疼。我的基类如下所示:
public abstract class Equipment<T> where T:EquipmentData { }
现在的孩子可能看起来像:
public class Weapon : Equipment<WeaponData> { }
与
public class WeaponData : EquipmentData { }
类似的还有:
public class Shield : Equipment<ShieldData> { }
public class ShieldData : EquipmentData { }
现在我需要一个包含Equipment<T> 的子级的列表,但显然List<T> 要求我更具体,例如List<Equipment<EquipmentData>>。但是,当我尝试将Weaponobject 添加到该列表时,我收到无法将Weapon 转换为Equipment<EquipmentData> 的错误。当然,将列表更改为 List<Equipment<WeaponData>> 会起作用,但是出于同样(显而易见的)原因,我将无法将 Shieldobjects 添加到该列表中。
本质上我的问题是是否有某种方法可以使列表成为一个
List<Equipment<child ofEquipmentData>> 这样它就需要Weapon 对象以及Shieldobjects?
【问题讨论】:
-
这是对泛型的错误使用。不要这样做。正如您所发现的,当您尝试组合多种多态性时,它会导致问题。请参阅我的系列ericlippert.com/2015/04/27/wizards-and-warriors-part-one,了解更多关于这种模式的具体想法,以及在 FRP 游戏中表示武器的类似模式。
-
任何时候你有一个模式,其中有两个类层次结构必须保持同步并通过约束相互关联,你就会遇到这样的问题。参数化基类不会给你带来什么。
-
如果您坚持,请参阅第一个副本以获取选项。您必须为
Equipment<T>创建一个非泛型基类型,因此您的所有类都共享一个它们都兼容的类型。但恕我直言,这是一个糟糕的方式(对不起,马克)。请参阅第二个标记的副本以了解您为什么不想这样做的信息,当然还有 Eric 的很好的系列文章,该系列阐述了该主题。 -
@EricLippert 我明白你的意思。不过,它实际上不是一个同步的层次结构。通常所有
Equipment共享相同的EquipmentData只是在少数情况下需要额外数据(例如射击的视觉效果(射击、轨迹、冲击)或武器子弹的速度或我需要EquipmentData的孩子的船周围的盾牌(模型,材料))。出于工作流程的原因,我尝试将EquipmentData和来自武器的特殊数据保留在同一个对象中,以便通过 Unity Inspector 更轻松地进行平衡操作。