Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';t强制转换为派生类的继承类字段_C#_Inheritance_Unity3d_Architecture_Overriding - Fatal编程技术网

C# Can';t强制转换为派生类的继承类字段

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

在我解释我的问题之前,请记住,我选择了这样的体系结构,因为这将在Unity下的库存系统中使用,所以我必须将
分离出来,这是一个单一行为,它只是世界上的某个东西,而它的数据只是用于库存目的的值。。。如果这有道理的话

我有一个这样的架构:

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; }