我正在Unity中编写一款游戏,其中包含很多可以在玩家清单中使用的物品。有一个基类ItemSettings,它具有所有项目都包含的属性,然后是枪,零件,装甲等的一级派生类型。所有项目都由枚举值唯一标识,我有一个类来管理该字典枚举=>项目的设置。
基本类层次结构:
class ItemSettings {
public Item itemIdenfitier;
public ItemCategory itemCategory;
}
class GunSettings : ItemSettings {...}
class ComponentSettings: ItemSettings {...}
这是为所有ItemSettings类型维护词典的单例类,并且是允许调用者检索特定项目设置的函数:
public static TItemType Get<TItemType>(Item item) where TItemType : ItemSettings
{
ItemSettings itemSetting;
switch (Instance.itemCategoryMap[item])
{
case ItemCategory.Gun:
itemSetting = Instance.gunMap[item];
break;
case ItemCategory.Component:
itemSetting = Instance.componentMap[item];
break;
default:
throw new ArgumentOutOfRangeException($"Item category not found for item {item}");
}
return (TItemType) itemSetting;
}
我不明白为什么我必须以这种方式进行转换,而不是像这样自己返回字典值:
public static TItemType Get<TItemType>(Item item) where TItemType : ItemSettings
{
switch (Instance.itemCategoryMap[item])
{
case ItemCategory.Gun:
return Instance.gunMap[item];
case ItemCategory.Component:
return Instance.componentMap[item];
default:
throw new ArgumentOutOfRangeException($"Item category not found for item {item}");
}
}
我得到了错误:
Cannot implicitly convert type GunSettings to TItemType
但是,TItemType具有必须为ItemSettings的约束,该约束应适用于GunSettings。我一定想念C#泛型系统的细微差别。
答案 0 :(得分:2)
您的调用代码如下:
GunSettings setting = Get<GunSettings>(item);
但是,如果物品是一个组件而不是一把枪怎么办?然后就无法将其投放到GunSetting。进行显式转换是必需的,因为虽然您可能知道该函数将始终获取正确子类型的ItemSettings实例,但编译器却不会。