在我的游戏中,我有商人。所有商品都有标准价格。每个商家都有这个价格的解释。我有一个项继承层次结构。 ConsumableItem
和EquipableItem
继承自基类GameItem
,HoldableEquipableItem继承自EquipableItem,依此类推。商家可以为这些类型之一添加乘数,因此如果他在EquipableItem上的乘数为0.5,则表示EquipableItem,从中继承的所有类型的价格都会乘以0.5(减半)。
继承层次结构适合我的问题,因为它不必在任何地方重新输入,工具Type.IsSubclassOf
是内置的。但我不太喜欢使用游戏机制类型,主要是因为我想在Unity检查器中显示类型并且它不支持Type,因此我必须使用字符串对其进行符号化并在之后解析该类型(也可能是“道德”和性能问题?)。
我是否有一种很好的方法可以用字符串或enum
类型而不是Type来实现它?使用类似于IsSubclassOf
的方法的类,只使用字符串/枚举。项的类型可以通过字段/属性反映,也可以只将层次结构中的GetType
转换为字符串/枚举版本。
答案 0 :(得分:0)
在你的情况下我会选择这样的东西:
public class GameItem {
public List<string> Type { get; private set; }
GameItem(List<string> type)
{
Type = type;
Type.Add(nameof(GameItem))
}
public IsType(string type)
{
return Type.Contains(type);
}
}
public class SubGameItem : GameItem
{
public SubGameItem(List<string> type)
: base(new List<string>(type){nameof(SubGameItem)})
{
}
}
如果这对您来说太难编码,我将不得不说我不明白为什么,我认为这是解决问题的最难硬编码方式,它可能比使用Type类更好。
如果你没有c#6,你将不得不硬编码,但在这种情况下我会使用枚举而不是字符串(无论如何我会使用枚举,但如果你不想要确保你更新了每次更改的枚举,这很好。)
答案 1 :(得分:0)
我忘记发帖了。如果有人需要,这是我解决问题的方法。
/// <summary>
/// Mimics the Type inheritance hierarchy for enums
/// </summary>
// Enum is a special class that cannot be used as a constraint, so instead use its parent interface IConvertible
public class InheritanceHierarchy<T> where T : IConvertible
{
private Dictionary<T, InheritanceElement<T>> elements =
new Dictionary<T, InheritanceElement<T>>();
public void Add(T element, T parent)
{
var parentElement = parent.Equals(default(T)) ? null : elements[parent];
elements.Add(element, new InheritanceElement<T>(element, parentElement));
}
/// <summary>
/// Add parent for multiple children
/// </summary>
public void Add(T parent, params T[] elements)
{
foreach (var element in elements)
Add(element, parent);
}
public bool IsSameOrSubclass(T element, T parent)
{
return ParentIndex(element, parent) != -1;
}
/// <summary>
/// Get how many parents the element is from parent. If they don't relate return -1
/// </summary>
public int ParentIndex(T element, T parent)
{
// If the element is same as parent
if (element.Equals(parent))
return 0;
// Loop through the chain of parents checking until it is either null or a match
var actualParent = elements[element].parent;
var parentIndex = 1;
while (actualParent != null)
{
if (parent.Equals(actualParent.element))
return parentIndex;
else
{
actualParent = actualParent.parent;
parentIndex++;
}
}
return -1;
}
}
public class InheritanceElement<T> where T : IConvertible
{
public T element;
public InheritanceElement<T> parent;
public InheritanceElement(T element, InheritanceElement<T> parent)
{
this.element = element;
this.parent = parent;
}
}