在解释问题之前,请记住我选择了这样的架构,因为它将在Unity下的清单系统中使用,因此我必须将Item
分开,这是一个MonoBehavior,它只是来自其数据的世界,这些数据仅是用于库存目的的值...如果有道理。
我有这样的架构:
public class ItemData
{
// some fields...
public string _name; //should be private with its properties but it doesn't matter in the current example
}
public class EquipmentData : ItemData
{
// some additional fields...
public float _weight;
}
public class Item
{
private ItemData _data;
//Properties
public virtual ItemData Data { get; set; }
}
public class Equipment : Item
{
//Properties
public override ItemData Data
{
get { return _data as EquipmentData; }
set { _data = value as EquipmentData; }
}
}
因此,基本上,我的项目层次结构更加深入,但1级足以说明我自己。 (它像武器:设备一样继续前进)...
问题是,如果我将
private ItemData _data;
留在Item
类中,并在private EquipmentData _eData;
类中添加一个Equipment
,由于ItemData
继承了EquipmentData
等,我将有两次ItemData
字段。其他派生类...如果我有一个从Equipment
派生的类,则第三次获取它...就像是:
public class Item
{
private ItemData _data;
}
public class Equipment : item
{
private EquipmentData _eData;
}
ItemData
之类的字段,例如_name
将在Equipment
中出现两次,但我不希望如此...因此,我猜我的体系结构有问题,可能有一种解决方法,看起来有点“肮脏”,但我无法在线找到针对此问题的任何特定方法,并且已经达到了极限。
我尝试过的
我试过在
new
中使用关键字Equipment
认为可以隐藏我的protected ItemData _data;
类中的初始Item
,然后在protected new EquipmentData _data;
中包含Equipment
,但是自从Shadow _data必须为相同类型,似乎不适用于派生类型。另外,如我的代码示例所示,我尝试覆盖属性以根据调用的类返回正确的类型,强制转换始终返回
null
...我仍然感到奇怪的是,我最终尝试实现类似的东西,因此我乐于接受新想法以更好的方式重组事物,或者如果有人有解决方案,我没有想到保留那样的方式,而是他们工作,这将是非常好的。
我希望我对问题有足够的了解,如果没有的话,我可以根据需要解决。
最佳答案
您需要的是Generic Classes。这样,您可以为每个Item
分配其正确的ItemData
类型。因此,将为Equipment
分配其EquipmentData
。
//TItemData is a name of this generic type.
//It could be T for example, just like variable name.
//These type names start from T by convention.
//This is not a new class or something like that.
//where TItemData : ItemData is a constraint,
//that assumes that this type should be a subtype of ItemData
public abstract class Item<TItemData> where TItemData : ItemData
{
protected TItemData Data;
}
//EquipmentData is a subtype of ItemData, so it fits here.
//No chances to write, for example, IntEquipment : Item<int> ,
//because int does not derive from ItemData.
public class Equipment : Item<EquipmentData>
{
//here Data will be of EquipmentData type, without any casting.
}
通过实现上述内容,您将实现Type Safety。
编辑
为了使一个类正确地扩展
Equipment
(我们称其为Weapon
)并具有其正确的ItemData
(我们称其为WeaponData
),您需要编写如下代码:编辑
Equipment
,并将其设置为abstract
:public abstract class Equipment<TEquipmentData>
: Item<TEquipmentData>
//this constraint is VERY important, as EquipmentData derives from ItemData, thus fulfill Item<TItemData> constraint.
where TEquipmentData : EquipmentData
{
//Data will have EquipmentData type here.
}
创建
WeaponData
public WeaponData : EquipmentData
{
}
创建
Weapon
public class Weapon : Equipment<WeaponData>
{
//Data will have WeaponData type here.
}