C# Can';t强制转换为派生类的继承类字段
在我解释我的问题之前,请记住,我选择了这样的体系结构,因为这将在Unity下的库存系统中使用,所以我必须将C# Can';t强制转换为派生类的继承类字段,c#,inheritance,unity3d,architecture,overriding,C#,Inheritance,Unity3d,Architecture,Overriding,在我解释我的问题之前,请记住,我选择了这样的体系结构,因为这将在Unity下的库存系统中使用,所以我必须将项分离出来,这是一个单一行为,它只是世界上的某个东西,而它的数据只是用于库存目的的值。。。如果这有道理的话 我有一个这样的架构: public class ItemData { // some fields... public string _name; //should be private with its properties but it doesn't matter
项
分离出来,这是一个单一行为,它只是世界上的某个东西,而它的数据只是用于库存目的的值。。。如果这有道理的话
我有一个这样的架构:
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; }
}
}
所以,基本上我有一个更深层次的项目层次结构,但一个层次足以解释我自己。(它像武器:装备一样继续运转)
问题是,如果我离开private ItemData\u data编码>在项中
类,并添加一个专用设备数据_eData
在Equipment
类中,我将有两个ItemData
字段,因为EquipmentData
继承了ItemData
等其他派生类。。。如果我有一个从设备
等派生的类,第三次得到它
比如:
public class Item
{
private ItemData _data;
}
public class Equipment : item
{
private EquipmentData _eData;
}
ItemData
的字段,如\u name
将在设备中出现两次,我不希望这样
所以我猜我的架构有问题,可能有一种方法看起来有点“脏”,但我在网上找不到解决这个问题的具体方法,我已经达到了极限
我所尝试的:
- 我曾尝试在
设备中使用关键字new
,认为我可以隐藏初始受保护的ItemData\u数据代码>在我的项目
类中,然后有受保护的新设备数据\u数据代码>在设备中
但它显然不允许我对数据进行阴影处理,因为它需要相同的类型,似乎不适用于派生类型
- 此外,如我的代码示例所示,我已尝试重写属性以根据调用它的类返回正确的类型,强制转换总是返回
null
我仍然觉得奇怪,我最终试图实现这样的东西,所以我愿意接受新的想法,以更好的方式重组事情,或者如果有人有一个我没有想到的解决方案,让事情保持这种方式,但让他们工作,那将是非常好的
我希望我的问题足够详细,如果没有的话,我可以在需要的时候把事情弄清楚。你需要的是。通过此操作,您可以为每个项目指定其适当类型的ItemData
。因此,设备
将分配其设备数据
//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.
}
创建武器数据
public WeaponData : EquipmentData
{
}
创建武器
public class Weapon : Equipment<WeaponData>
{
//Data will have WeaponData type here.
}
公共级武器:装备
{
//这里的数据将具有武器数据类型。
}
这项工作:
public class OverridePropertiesWithSameField
{
public void Test()
{
ChildItem ci = new ChildItem();
ChildItemData cid = new ChildItemData();
cid.ItemDataProp = "ItemDataProperty"; // Inherited
cid.ChildItemDataProp = "ChildItemDataProp"; // Specific
ci.ItemData = cid;
// You know you need ChildItemData type here.
var childItemData = ci.ItemData as ChildItemData;
string itemDataProp = childItemData.ItemDataProp;
string childItemDataProp = childItemData.ChildItemDataProp;
}
}
public class Item
{
protected ItemData data;
public virtual ItemData ItemData { get; set; }
}
public class ChildItem : Item
{
public override ItemData ItemData
{
get { return base.data; }
set { base.data = value; }
}
}
public class ItemData
{
public string ItemDataProp { get; set; }
}
public class ChildItemData : ItemData
{
public string ChildItemDataProp { get; set; }
}
可以使用泛型类型参数和泛型类型约束(其中)
公共类项目,其中数据:ItemData
{
公共虚拟数据{get;set;}
}
现在,您的类可以使用特定的ItemData:
Item<ItemData> has property
public virtual ItemData Data { get; set; }
Item<EquipmentData> has property
public virtual EquipmentData Data { get; set; }
Item<ANOTHER> has property
public virtual ANOTHER Data { get; set; }
项具有属性
公共虚拟ItemData数据{get;set;}
项目具有属性
公共虚拟设备数据{get;set;}
项目具有属性
公共虚拟另一个数据{get;set;}
您当前的设计有什么问题?为什么private
itemdata而不是protected
?因为我通过属性访问它。我试图重写属性,使每个派生类具有相同的字段,但通过重写每个派生类中的属性,从属性返回该字段的强制转换版本。c、 f.我的代码片段问题是,强制转换总是返回null,因为它无法成功地将EquipmentData
强制转换为ItemData
…我猜您在重写的道具中做的是相反的,这将不起作用。请看下面我的回答。我会试试的。我只是在获取TItemData
和ItemData
之间的差异时遇到了一个问题,请帮我澄清一下好吗?非常感谢。编辑,它澄清了一些事情吗?哦,是的,刚刚意识到我的问题有多愚蠢。。。谢谢,我会尝试哦,为了细节起见,我想我们可以指出,ITemData
应该是ITemData
,第一个T上没有大写字母,但它不会改变你的解释,我猜只是一个拼写错误。好吧,这是一个语法问题,但是我有一个武器
类,它是从装备
派生出来的。我试过公共级武器:装备,显然不起作用,但我找不到正确的语法。它需要从设备
派生,而不是直接从项目
派生。。。有什么建议吗?Nevermind,找到了答案这有点接近@DreamOnJava所建议的,但是这里你没有考虑到我的类的继承,这就是我在尝试实现这个解决方案时遇到的问题。在我看来,你真的不需要继承这个属性,只要改变它的类型就可以了。类型参数和约束是缺少的成分。如果通过更改类型意味着更改属性的返回类型,我尝试了,但它不允许我这样做。我还尝试保持相同的返回类型,并在get{}中强制转换返回的变量,但遗憾的是,这就是我从中获取null
的原因:不,我的意思是使用一个类型参数,使属性具有您需要的类型。哦,是的,所以是的,它看起来确实像来自dreamonjava的答案,我会尝试一下,让你们知道,谢谢你们的时间,所以我确实尝试过了,演员阵容再次返回null。。。看起来是这样的:EquipmentData=\u data作为EquipmentData;data.Type=ItemType.EType.device
(其中,\u data
是项
类中继承的受保护字段),但是当我到达第二行,尝试使用数据
中的内容时,它是空的
。。。哪一种是有意义的,因为它不是从一个适当的i
public class Item<DATA> where DATA : ItemData
{
public virtual DATA Data { get; set; }
}
Item<ItemData> has property
public virtual ItemData Data { get; set; }
Item<EquipmentData> has property
public virtual EquipmentData Data { get; set; }
Item<ANOTHER> has property
public virtual ANOTHER Data { get; set; }