在解释问题之前,请记住我选择了这样的架构,因为它将在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.
}

10-06 07:35