C# 保存相关常数的最佳实践?

C# 保存相关常数的最佳实践?,c#,types,lookup,C#,Types,Lookup,在我的游戏中,我有一个不同GameEntityTypes的枚举(大约200个入口) 保存游戏时,仅将GameEntityType数组写入保存文件 重建游戏世界,并显示有关GameEntityTypes 我需要有一个列表,其中有很多额外的细节(常量值)。 这意味着每个GameEntityType都有与之关联的其他值。 这些值经常在每一帧访问。 我的目标是用一种简单的方法从GameEntityTypeID(枚举)中获取所有额外信息。 例如,当我从保存文件中读取0x1时,我可以简单地访问名称和所有其他

在我的游戏中,我有一个不同
GameEntityType
s的枚举(大约200个入口)

保存游戏时,仅将
GameEntityType
数组写入保存文件

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

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

类型:
string
,string,
标志枚举:“视觉分类”
bool
bool
价值观:
“StoneBlock”
“Stone\u Texture.DDS”
0x0102
false
true

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

公共静态常量字符串[]={“StoneBlock”,…
[more entrys]
}

当然,这是一个糟糕的解决方案,因为我不能只添加GameEntityType 无论我想去哪里,都不必更新所有其他列表。 我还必须将逻辑单元划分为数据类型单元(这是一个问题!因为当我决定不再需要特定的EntityType时,我必须遍历6个以上的列表!)

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

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

类似于此的查找最好是通过子类化“Constants.TextureList[
GameEntityType
]”

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);
}
}
公共抽象类枚举:IComparable
{
私有只读int_值;
私有只读字符串_displayName;
受保护枚举()
{
}
受保护的枚举(int值、字符串显示名)
{
_价值=价值;
_displayName=displayName;
}
公共整数值
{
获取{返回_值;}
}
公共字符串显示名
{
获取{return\u displayName;}
}
公共重写字符串ToString()
{
返回显示名;
}
公共静态IEnumerable GetAll(),其中T:Enumeration,new()
{
var类型=类型(T);
var fields=type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
foreach(字段中的var信息)
{
var instance=newt();
var locatedValue=info.GetValue(实例)作为T;
if(locatedValue!=null)
{
收益率-收益率-定位价值;
}
}
}
公共覆盖布尔等于(对象对象对象)
{
var otherValue=obj作为枚举;
if(otherValue==null)
{
返回false;
}
var typeMatches=GetType().Equals(obj.GetType());
var valueMatches=_value.Equals(otherValue.value);
返回typeMatches&&valueMatches;
}
公共覆盖int GetHashCode()
{
返回_value.GetHashCode();
}
公共静态int绝对差异(枚举第一个值、枚举第二个值)
{
var absoluteDifference=Math.Abs(firstValue.Value-secondValue.Value);
返回绝对差;
}
公共静态T FromValue(int值),其中T:Enumeration,new()
{
var matchingItem=parse(value,“value”,item=>item.value==value);
返回匹配项;
}
公共静态T FromDisplayName(字符串displayName),其中T:Enumeration,new()
{
var matchingItem=parse(displayName,“displayName”,item=>item.displayName==displayName);
返回匹配项;
}
私有静态T parse(K值,字符串描述,Func谓词),其中T:Enumeration,new()
{
var matchingItem=GetAll().FirstOrDefault(谓词);
if(matchingItem==null)
{
var message=string.Format(“{0}”不是有效的{2}”中的{1}”,值、说明、类型(T));
抛出新的ApplicationException(消息);
}
返回匹配项;
}
公共整数比较(对象其他)
{
返回值.CompareTo(((枚举)其他).Value);
}
}

这里有一篇文章:

我不确定我是否完全理解您想要了解的内容,但如果您需要快速查找,听起来您想要的是一本
词典。

什么是texturelist?这与您的gameentitytypes有什么关系?这是一个列表,我可以在其中查找实体使用的纹理。还有一些其他列表:EntityType所隐含的每个附加值都有一个列表(或数组)。澄清问题:把它想象成一个存储所有不同EntityType和匹配值的“仅查找SQL表”,列为:GameEntityType(uint);纹理(字符串);颜色(int[3])。。。这个数据表使我能够只保存EntityType(小的保存文件),然后用EntityType和LookupTable的组合信息重新创建游戏世界谢谢,这正是我想要的。