我的枚举类型可以有友好的名称吗?
问题的出现原因:
枚举类型在使用时只能直接使用枚举值,不能直接获取友好的名称。这导致在代码中使用枚举值时可读性较差,不容易理解。
解决方法:
使用扩展方法为枚举类型添加一个方法,该方法根据枚举值返回一个友好的名称。代码如下:
namespace Extension { public static class ExtensionMethods { public static string EnumValue(this MyEnum e) { switch (e) { case MyEnum.First: return "First Friendly Value"; case MyEnum.Second: return "Second Friendly Value"; case MyEnum.Third: return "Third Friendly Value"; } return "Horrible Failure!!"; } } }
使用该扩展方法,可以通过枚举值调用该方法获取友好的名称。例如:
Console.WriteLine(MyEnum.First.EnumValue());
这样就可以在代码中更加直观地使用枚举值了。
注意事项:
需要注意的是,switch语句是一种线性搜索,其复杂度为O(n),在最坏情况下需要与枚举中的每个值进行比较。不过,根据实现细节,C#编译器有时会使用字典查找来优化switch语句的性能。
参考资料:
- [Are .NET switch statements hashed or indexed?](http://stackoverflow.com/questions/3366376/3366497#3366497)
枚举值的名称必须遵循C#中所有标识符的命名规则,因此只有第一个名称是正确的。
可以使用System.ComponentModel.DataAnnotations
并添加一个显示属性(例如:[Display(Name = "This Name doesn't work")]
)。
Cas的评论实际上是大多数人现在使用的解决方法。
不再起作用。
以防万一有人尝试在旧版本的.NET中使用Display
,它仅支持到.NET 4.5.2。 learn.microsoft.com/en-us/dotnet/api/…
Thomas Levesque的答案应该被设置为被接受的答案。
如果我这样做:EnumType.member,它只显示为“member”,而不是显示名称...
在C#中,枚举类型的每个值都有一个与之关联的整数值。默认情况下,枚举值的名称就是它们的整数值。然而,有时候我们希望为枚举值指定一个友好的名称,以便在代码中更容易理解和使用。
为了解决这个问题,我们可以使用Description
属性。下面的代码是一个扩展方法,可以根据给定的枚举值获取其描述:
public static string GetDescription(this Enum value)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
FieldInfo field = type.GetField(name);
if (field != null)
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
{
return attr.Description;
}
}
}
return null;
}
使用这个方法非常简单,只需要在枚举值上添加Description
属性,然后调用GetDescription()
方法即可:
public enum MyEnum
{
[Description("Description for Foo")]
Foo,
[Description("Description for Bar")]
Bar
}
MyEnum x = MyEnum.Foo;
string description = x.GetDescription();
这段代码中,MyEnum
枚举类型的两个值分别被指定了友好的名称。当我们调用GetDescription()
方法时,就可以获取到相应的描述。
另外,某些情况下了一个问题,即在使用Visual Studio的Intellisense功能时,它会显示所有值类型的方法,而不仅仅是枚举类型的方法。这可能是一个VS2008的bug,在VS2010中已经修复了。
此外,还有一个需要注意的地方是,代码中使用到了System.ComponentModel
和System.Reflection
这两个命名空间。有些人可能不会将它们包含在代码中,因为它们只会增加噪音。然而,使用Visual Studio可以轻松地自动添加这些命名空间。
还有一位开发者建议将return null
改为return value.ToString()
,这样Description
属性就变成了可选的。
最后,某些情况下了反射的性能问题。由于反射操作较慢,建议将枚举值的描述缓存到一个字典中,以提高性能。经过测试,这样的改动可以将性能提升10倍。