【发布时间】:2011-11-01 12:02:39
【问题描述】:
基本上一系列标题将被传递到 switch 语句中,我需要将它们与枚举的字符串值进行比较。但我几乎不知道如何正确地做到这一点。
另外,我不知道这是否是最好的方法,所以如果有人有任何想法?
例如:
enum
{
doctor = "doctor",
mr = "mr",
mrs = "mrs"
}
然后切换我分配给它们的字符串值。
【问题讨论】:
基本上一系列标题将被传递到 switch 语句中,我需要将它们与枚举的字符串值进行比较。但我几乎不知道如何正确地做到这一点。
另外,我不知道这是否是最好的方法,所以如果有人有任何想法?
例如:
enum
{
doctor = "doctor",
mr = "mr",
mrs = "mrs"
}
然后切换我分配给它们的字符串值。
【问题讨论】:
我发现对我来说最好的方法是在枚举值上使用System.ComponentModel.DescriptionAttribute 属性。
这是一个例子:
using System.ComponentModel;
public enum ActionCode
{
[Description("E")]
Edit,
[Description("D")]
Delete,
[Description("R")]
Restore
}
然后,要使用它,请在静态类上创建一个扩展方法,如下所示:
编辑:我重写了该方法以包含来自 Laurie Dickinson 的一个很好的建议,以便该方法在没有 Description 属性时返回枚举值的名称。我还重构了该方法以尝试改进功能。它现在适用于所有枚举,无需使用 IConvertible。
public static class Extensions
{
public static string GetDescription(this Enum e)
{
var attribute =
e.GetType()
.GetTypeInfo()
.GetMember(e.ToString())
.FirstOrDefault(member => member.MemberType == MemberTypes.Field)
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.SingleOrDefault()
as DescriptionAttribute;
return attribute?.Description ?? e.ToString();
}
}
所以,要获取与我们上面的枚举关联的字符串,我们可以使用以下代码:
using Your.Extension.Method.Namespace;
...
var action = ActionCode.Edit;
var actionDescription = action.GetDescription();
// Value of actionDescription will be "E".
这是另一个示例枚举:
public enum TestEnum
{
[Description("This is test 1")]
Test1,
Test2,
[Description("This is test 3")]
Test3
}
这是查看描述的代码:
var test = TestEnum.Test2;
var testDescription = test.GetDescription();
test = TestEnum.Test3;
var testDescription2 = test.GetDescription();
结果将是:
testDescription: "Test2"
testDescription2: "This is test 3"
我想继续发布通用方法,因为它更有用。它使您不必为所有枚举编写自定义扩展。
【讨论】:
First() 并消除默认值。我相信我们几乎可以保证在这一点上有一个值,因为它是一个枚举。它不应该为空。
您不能有一个基础类型为string 的enum。 The underlying type can be any integral type except char.
如果您想将string 转换为您的enum,那么您可能需要使用Parse 或TryParse 方法。
string incoming = "doctor";
// throws an exception if the string can't be parsed as a TestEnum
TestEnum foo = (TestEnum)Enum.Parse(typeof(TestEnum), incoming, true);
// try to parse the string as a TestEnum without throwing an exception
TestEnum bar;
if (Enum.TryParse(incoming, true, out bar))
{
// success
}
else
{
// the string isn't an element of TestEnum
}
// ...
enum TestEnum
{
Doctor, Mr, Mrs
}
【讨论】:
我想为使用 C# 6 或更高版本的任何人添加另一个答案。
如果您只想获取 Enum 值的名称,可以使用 C# 6 中引入的新 nameof() 方法。
string enumName = nameof(MyEnum.EnumVal1); // enumName will equal "EnumVal1"
虽然乍一看这似乎有点过头了(为什么不直接将字符串的值设置为“EnumVal1”呢?),但它会为您提供编译时检查以确保该值有效。因此,如果您更改了枚举值的名称而忘记告诉您的 IDE 查找和替换所有引用,则在您修复它们之前它不会编译。
【讨论】:
这不是应该硬编码的东西。它应该是数据驱动的,可能从外部文件或数据库中读取。您可以将它们存储在 Dictionary 中并使用密钥来驱动您的逻辑。
【讨论】:
我认为执行此操作的标准方法是使用具有只读字符串属性的静态类,该属性返回您想要的值。
【讨论】:
枚举不能是字符串类型。
允许的枚举类型为 byte、sbyte、short、ushort、int、uint、long 或 ulong。
【讨论】:
枚举只能具有整数基础类型(char 除外)。因此你不能做你想做的事,至少不能直接做。
但是你可以将你拥有的字符串翻译成枚举类型:
EnumType eVal = (EnumType)Enum.Parse(typeof(EnumType), strValue);
switch(eVal)
{
case EnumType.doctor:/*...*/; break;
case EnumType.mr: /*...*/; break;
}
【讨论】:
为什么不只使用纯枚举和开关?
enum Prefix
{
doctor,
mr,
mrs
}
然后你可以使用就像
string case = "doctor";
switch ((Prefix)Enum.Parse(typeof(Prefix), "doctor"))
{
case Prefix.doctor:
...
break;
...
default:
break;
}
【讨论】:
Dictionary<string, Prefix> map,填充它,然后给一个字符串“Lance Corporal”,找到一个合适的枚举值(比如Prefix p = map["Lance Corporal"];),然后切换枚举类型。跨度>
只是分享我的解决方案。通过下载 nuget 包 Extension.MV,可以使用一种方法从枚举描述中获取字符串
public enum Prefix
{
[Description("doctor")]
doctor = 1,
[Description("mr")]
mr = 2,
[Description("mrs")]
mrs = 3
}
public static class PrefixAdapter {
public static string ToText(this Prefix prefix) {
return prefix.GetEnumDescription();
}
public static Prefix ToPrefix(this string text) {
switch (text)
{
case "doctor"
return Prefix.doctor;
case "mr"
return Prefix.mr;
case "ms"
return Prefix.mrs;
}
}
}
【讨论】:
阅读this tutorial 以了解枚举的工作原理。还有switch 语句的例子。
【讨论】:
如果你真的是铁杆并且使用 c# 8...
public static string GetDescription(this VendorContactType enumval) =>
enumval switch {
VendorContactType.AccountContact => "Account Contact",
VendorContactType.OrderContact => "Order Contact",
VendorContactType.OrderContactCC => "Order Contact CC",
VendorContactType.QualityContact => "Quality Contact",
VendorContactType.ShippingContact => "Shipping Contact",
_ => ""
};
我意识到这不会接受您程序的所有枚举,但这是我使用的并且我喜欢它。
【讨论】: