保存相关常量的最佳实践?

时间:2011-02-18 01:41:14

标签: c# types lookup

在我的游戏中,我有一个枚举(大约200个委托长)与不同的GameEntityType s。

保存游戏时,只会将一个GameEntityType数组写入保存文件。

重建游戏世界,并显示有关GameEntityTypes的各种信息 我需要列出一些额外的细节(常量值)。 这意味着每个GameEntityType都有与之关联的其他值。 每帧都经常访问这些值。 我的目标是通过一种简单的方法从GameEntityTypeID(枚举)中获取所有额外信息。 例如,当我从保存文件中读取0x1时,我可以简单地访问名称和所有其他名称 与数组/枚举隐含的信息,如下所示:“Constants.TextureList [GameEntityType]”,将返回字符串"Stone_Texture.DDS"

第一个枚举条目的附加/关联信息的示例:

类型: string,字符串,Flag-Enum: "Visual-Classification"boolbool 价值观: "StoneBlock""Stone_Texture.DDS"0x0102falsetrue

我的第一个方法是创建一个静态的GameEntityTypeInfo类 每个附加信息类型都有如下所示的成员:

public static const string [] = {“StoneBlock”,... [more entrys]};

当然这是一个糟糕的解决方案,因为我不能只添加GameEntityType 我想要的任何地方,而不必更新所有其他列表。 我还必须将逻辑单元分成数据类型单元(这是一个问题!因为当我决定我不再需要特定的EntityType时,我必须通过6个以上的列表!)

接下来,我试图通过从这些数据集中创建一个结构来解决这个问题 并将它们添加到静态数组中。 但是在构造函数(游戏开始时)创建带有附加信息的List 仍然不是最好的解决方案。

问题:如何创建快速(名称/分类查找将每帧至少使用5000次)并轻松访问(最好使用索引器)这些常量值?

类似于此的查找将是最好的“Constants.TextureList [GameEntityType]”

2 个答案:

答案 0 :(得分:2)

通过子类化:

public abstract class Enumeration : IComparable
{
private readonly int _value;
private readonly string _displayName;

protected Enumeration()
{
}

protected Enumeration(int value, string displayName)
{
    _value = value;
    _displayName = displayName;
}

public int Value
{
    get { return _value; }
}

public string DisplayName
{
    get { return _displayName; }
}

public override string ToString()
{
    return DisplayName;
}

public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
{
    var type = typeof(T);
    var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

    foreach (var info in fields)
    {
        var instance = new T();
        var locatedValue = info.GetValue(instance) as T;

        if (locatedValue != null)
        {
            yield return locatedValue;
        }
    }
}

public override bool Equals(object obj)
{
    var otherValue = obj as Enumeration;

    if (otherValue == null)
    {
        return false;
    }

    var typeMatches = GetType().Equals(obj.GetType());
    var valueMatches = _value.Equals(otherValue.Value);

    return typeMatches && valueMatches;
}

public override int GetHashCode()
{
    return _value.GetHashCode();
}

public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
{
    var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
    return absoluteDifference;
}

public static T FromValue<T>(int value) where T : Enumeration, new()
{
    var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
    return matchingItem;
}

public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
{
    var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
    return matchingItem;
}

private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
{
    var matchingItem = GetAll<T>().FirstOrDefault(predicate);

    if (matchingItem == null)
    {
        var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
        throw new ApplicationException(message);
    }

    return matchingItem;
}

public int CompareTo(object other)
{
    return Value.CompareTo(((Enumeration)other).Value);
}
}

这里有一篇文章:http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx

答案 1 :(得分:0)

不确定我是否完全理解你想要了解的内容但是如果你在快速查找之后,它听起来像是Dictionary<string, List<string>>