如何将字符串值分配给枚举并在开关中使用该值

本文关键字:开关 枚举 字符串 分配 | 更新日期: 2023-09-27 18:13:22

基本上,一系列标题将被传递到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"

我想继续发布通用方法,因为它更有用。它可以防止您为所有枚举编写自定义扩展。

不能有一个底层类型为stringenum。基础类型可以是除char之外的任何整数类型。

如果您想将string转换为enum,那么您可能需要使用ParseTryParse方法。

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#或更高版本的人添加另一个答案。

如果您只想获得Enum值的名称,可以使用C#中引入的新nameof((方法。

string enumName = nameof(MyEnum.EnumVal1); // enumName will equal "EnumVal1"

虽然乍一看这可能有些过头了(为什么不直接将字符串的值设置为"EnumVal1"开始呢?(,但它会在编译时进行检查,以确保值有效。因此,如果您更改了枚举值的名称,却忘记告诉IDE查找和替换所有引用,那么在修复它们之前,IDE将不会进行编译。

这不是应该硬编码的事情。它应该是数据驱动的,可能是从外部文件或数据库中读取的。您可以将它们存储在Dictionary中,并使用这些密钥来驱动您的逻辑。

枚举不能为字符串类型。

枚举的批准类型有byte、sbyte、short、ushort、int、uint、long或ulong。

http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

Enum只能有整型底层类型(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;
}

只是分享我的解决方案。通过下载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;
        }
    }
}

阅读本教程,了解枚举是如何工作的。还有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",
            _ => ""
        };

我意识到这不会接受你程序的所有枚举,但这是我使用的,我喜欢它。