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的组合信息重新创建游戏世界谢谢,这正是我想要的。