[英]What's the best practice way to convert enum to string?
我有这样的枚举:
public enum ObectTypes
{
TypeOne,
TypeTwo,
TypeThree,
...
TypeTwenty
}
然后我需要将此枚举转换为字符串。 现在我这样做:
public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
string result = string.Empty;
switch (typeObj)
{
case ObjectTypes.TypeOne: result = "This is type T123"; break;
case ObjectTypes.TypeTwo: result = "Oh man! This is type T234"; break;
...
case ObjectTypes.TypeTwenty: result = "This is type last"; break;
}
return result;
}
我很确定有更好的方法可以做到这一点,我正在寻找一些良好的实践解决方案。
编辑 :结果字符串中没有一个模式。
提前致谢。
我使用System.ComponentModel
的[Description]
属性
例:
public enum RoleType
{
[Description("Allows access to public information")] Guest = 0,
[Description("Allows access to the blog")] BlogReader = 4,
}
然后从中读取我的意思
public static string ReadDescription<T>(T enumMember)
{
var type = typeof (T);
var fi = type.GetField(enumMember.ToString());
var attributes = (DescriptionAttribute[])
fi.GetCustomAttributes(typeof (DescriptionAttribute), false);
return attributes.Length > 0 ?
attributes[0].Description :
enumMember.ToString();
}
然后使用
ReadDescription(RoleType.Guest);
注意:此解决方案假设单个文化应用程序,因为没有特别询问有关多种文化的内容 如果您处于需要处理多种文化的情况,我会使用DescriptionAttribute
或类似方法将密钥存储到文化感知资源文件中。 虽然您可以将枚举成员直接存储在.resx文件中,该文件可以创建最紧密的耦合。 我认为没有理由要将应用程序的内部工作(枚举成员名称)与为国际化目的而存在的键值相结合。
如果您需要自定义字符串,最好的选择是创建一个Dictionary< ObjectTypes, string>
,然后只进行字典查找。
如果您对默认的ToString()功能没问题,只需使用typeObj.ToString();
对于字典方法,您可以:
private static Dictionary<ObjectTypes, string> enumLookup;
static MyClass()
{
enumLookup = new Dictionary<ObjectTypes, string>();
enumLookup.Add(ObjectTypes.TypeOne, "This is type T123");
enumLookup.Add(ObjectTypes.TypeTwo, "This is type T234");
// enumLookup.Add...
}
你的方法变成:
public string ConvertToCustomTypeName(ObjectTypes typeObj)
{
// Shouldn't need TryGetValue, unless you're expecting people to mess with your enum values...
return enumLookup[typeObj];
}
使用建议的资源方式:
string GetName(Enum e) {
return Properties.Resources.ResourcesManager.GetString("_enum_"+e.GetType().ToString().Replace('.','_'));
}
错误处理更多一点..
我认为最简单的方法是使用一个函数在枚举值和首选短名称之间进行映射,然后创建另一个生成完整消息的函数。
internal static string MapToName(ObjectTypes value) {
switch (value) {
case ObjectTypes.TypeOne: return "T123";
case ObjectTypes.TypeTwo: return "T234";
...
}
}
public string ConvertToCustomTypeName(ObjectTypes value) {
return String.Format("This is type {0}", MapToName(value));
}
我曾经在枚举字段上使用了一个自定义属性,它接受了一个字符串参数,然后写了一个函数来在给定一个枚举值时提取字符串。
如果你只想使用枚举的名称(即TypeOne),你可以简单地在枚举本身上调用ToString()
typeObj.ToString()
如果你想要一个基于类型的自定义字符串,你有几个不同的选项。 你拥有的switch语句是可以的,但如果你有大量的枚举,保持它会变得混乱。 或者您可以使用枚举类型作为键并使用字符串作为值来设置字典。
public enum ObectTypes
{
One,
Two
}
Dictionary<ObectTypes, String> myDic = new Dictionary<ObectTypes, string>();
myDic.Add( ObectTypes.One, "Something here for One" );
myDic.Add( ObectTypes.Two, "Something here for Two" );
我不太相信这个......为什么没有人建议资源文件?
将枚举值映射到已编译代码中的字符串是一个很好的快速黑客,但从长远来看,这是一个不好的做法,并且很难重构代码。 如果从枚举中添加(或减去)值,该怎么办? 如果您使用资源文件中的字符串,您只需添加(或删除)一个条目即可。
我会将这些值放在数据库中。 角色通常属于数据库,原因如下:
如果正确完成,性能不应成为从数据库获取角色的问题。 此外,由于角色定义表很少更改,因此它非常适合缓存。
如果你发现自己不得不在Enum周围进行攻击以使其工作,也许你不应该使用Enum。 给定正确的位置,一切都应该在代码中流动得更好,几乎没有黑客攻击。 授予的Enum有他们的位置; 例如,一个相当静态的互斥状态。
我要说,这需要重构。
你已经使用的并不是一个糟糕的模式。 几乎所有其他选项都有自己的问题。 如果您在此类型中使用F#,则可以执行以下操作:
type ObjectTypes =
| TypeOne
| TypeTwo
| TypeThree
...
| TypeTwenty
with override this.ToString() =
match this with
| TypeOne -> "This is type T123"
| TypeTwo -> "Oh man! This is type T234"
...
| TypeTwenty -> "This is type last"
| _ -> "This is any other type that wasn't explicitly specified"
当然,使用F#模式匹配,您可以获得比使用简单C#switch语句更多的控制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.