C#将继承层次结构复制为字符串/枚举格式

时间:2016-09-04 09:53:05

标签: c# inheritance unity3d

在我的游戏中,我有商人。所有商品都有标准价格。每个商家都有这个价格的解释。我有一个项继承层次结构。 ConsumableItemEquipableItem继承自基类GameItem,HoldableEquipableItem继承自EquipableItem,依此类推。商家可以为这些类型之一添加乘数,因此如果他在EquipableItem上的乘数为0.5,则表示EquipableItem,从中继承的所有类型的价格都会乘以0.5(减半)。

继承层次结构适合我的问题,因为它不必在任何地方重新输入,工具Type.IsSubclassOf是内置的。但我不太喜欢使用游戏机制类型,主要是因为我想在Unity检查器中显示类型并且它不支持Type,因此我必须使用字符串对其进行符号化并在之后解析该类型(也可能是“道德”和性能问题?)。

我是否有一种很好的方法可以用字符串或enum类型而不是Type来实现它?使用类似于IsSubclassOf的方法的类,只使用字符串/枚举。项的类型可以通过字段/属性反映,也可以只将层次结构中的GetType转换为字符串/枚举版本。

2 个答案:

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