C# 具有泛型的儿童列表

C# 具有泛型的儿童列表,c#,generics,C#,Generics,我需要在列表中保留一个基类的几个子类。通常情况下,这不是一个问题,但由于涉及到泛型,这让我感到头痛。我的基类如下所示: public abstract class Equipment<T> where T:EquipmentData { } 类似的还有: public class Shield : Equipment<ShieldData> { } public class ShieldData : EquipmentData { } 公共级屏蔽:设备{} 公共类Sh

我需要在列表中保留一个基类的几个子类。通常情况下,这不是一个问题,但由于涉及到泛型,这让我感到头痛。我的基类如下所示:

public abstract class Equipment<T> where T:EquipmentData { }
类似的还有:

public class Shield : Equipment<ShieldData> { }
public class ShieldData : EquipmentData { }
公共级屏蔽:设备{}
公共类ShieldData:EquipmentData{}
现在我需要一个包含
设备
的子项的列表,但显然
列表
要求我更加具体,比如
列表
。但是,当我尝试将
武器
对象添加到该列表时,我得到一个错误,即无法将
武器
转换为
设备
。当然,将列表更改为
list
会起作用,但由于同样(明显)的原因,我将无法将
Shield
对象添加到该列表中

从本质上说,我的问题是,是否有某种方法可以让这个列表成为一个


列表,这样它将需要
武器
对象以及
盾牌
对象?

我怀疑唯一的方法是添加一个通用的非泛型基类,也许:

public abstract class Equipment { }
public abstract class Equipment<T> : Equipment where T : EquipmentData { }
公共抽象类设备{}
公共抽象类设备:其中T:EquipmentData{}
使用
列表
,其中
设备
具有您需要访问的任何基本功能,而不知道其类型。如果将任何非特定成员添加到基类,则可以使用成员隐藏(
new
)在
设备
类型中使用更特定的类型重新声明它们


如果愿意的话,您可以使用
IEquipment
接口执行相同的操作。

这是泛型的一个糟糕用法。不要这样做。正如您所发现的,当您尝试组合各种多态性时,它会导致问题。请参阅我的系列文章,了解关于这个模式的更多想法,以及在FRP游戏中表示武器的类似模式。任何时候,当你有一个模式,其中有两个类层次结构必须保持同步,并通过约束相互关联时,你都会遇到类似的问题。参数化基类不会给您带来任何好处。如果您坚持,请参阅第一个副本以获取选项。您必须为
设备
创建一个非泛型基类型,以便所有类共享一个它们都兼容的类型。但我认为这是一种可怕的方式(对不起,马克)。请参阅第二个标记为重复的部分,了解您不想这样做的原因,当然还有Eric关于这个主题的非常好的系列文章。@EricLippert我明白您的意思。不过,它实际上不是一个同步的层次结构。通常所有的
设备
共享相同的
设备数据
只有在少数情况下,当需要额外的数据时(如射击的视觉效果(射击、痕迹、撞击)或武器的子弹速度或飞船周围盾牌的视觉效果(模型、材料)),我才需要
设备数据
。我试图将
装备数据
和来自武器的特殊数据保存在同一个对象中,以便于通过Unity Inspector进行平衡操作。因为问题是,当在列表中使用时,相关类型不能以协变方式变化,所以它们可能必须是接口。但我认为更好的设计是在两个并行类层次结构之间根本不存在这种关系。
public class Shield : Equipment<ShieldData> { }
public class ShieldData : EquipmentData { }
public abstract class Equipment { }
public abstract class Equipment<T> : Equipment where T : EquipmentData { }