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

C# 如何将字符串值分配给枚举并在开关中使用该值,c#,.net,enums,C#,.net,Enums,基本上,一系列标题将被传递到switch语句中,我需要将它们与枚举的字符串值进行比较。但我几乎不知道如何正确地做到这一点 此外,我不知道这是否是最好的方法,所以如果有人有任何想法 例如: enum { doctor = "doctor", mr = "mr", mrs = "mrs" } 然后切换我分配给它们的字符串值。了解枚举的工作原理。也有switch语句的示例。枚举不能是字符串类型 批准的枚举类型有byte、sbyte、short、ushort、int、uint、

基本上,一系列标题将被传递到switch语句中,我需要将它们与枚举的字符串值进行比较。但我几乎不知道如何正确地做到这一点

此外,我不知道这是否是最好的方法,所以如果有人有任何想法

例如:

enum
{
    doctor = "doctor",
    mr = "mr",
    mrs = "mrs"
}

然后切换我分配给它们的字符串值。

了解枚举的工作原理。也有
switch
语句的示例。

枚举不能是字符串类型

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

您不能使用底层类型为
字符串的

如果要将
字符串
转换为
枚举
,则可能需要使用or方法


这不是那种应该硬编码的东西。它应该是数据驱动的,可能从外部文件或数据库读取。您可以将它们存储在
字典中
并使用键驱动逻辑。

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;
}

我认为实现这一点的标准方法是使用具有只读字符串属性的静态类,该属性返回所需的值。

我发现最好的方法是使用枚举值上的
System.ComponentModel.DescriptionAttribute
属性

以下是一个例子:

using System.ComponentModel;

public enum ActionCode
{
    [Description("E")]
    Edit,
    [Description("D")]
    Delete,
    [Description("R")]
    Restore
}
然后,要使用它,请在静态类上创建一个扩展方法,如下所示:

Edit:我重写了该方法以包含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"

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

我想为使用C#6或更高版本的任何人添加另一个答案

如果只想获取枚举值的名称,可以使用C#6中引入的新nameof()方法


虽然乍一看这似乎有些过分(为什么不将字符串的值设置为“EnumVal1”作为开始?),但它将为您提供编译时检查,以确保该值有效。因此,如果您更改了枚举值的名称,而忘记告诉IDE查找和替换所有引用,则在您修复它们之前,它不会编译。

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

我浏览了一遍,但没有看到任何关于分配字符串值的内容。我没有说我希望它是字符串类型。我说我想给它赋值。我以前见过它,想知道如何实现它。很抱歉,我读它的时候也是一样的,因为基础值是枚举的类型。枚举必须是一个单词,所以例如,下士会给我带来问题。你可以创建一个映射
字典映射
,填充它,然后给它一个字符串“Lance Corporal”找到一个合适的枚举值(如
前缀p=map[“Lance下士”];
)并切换枚举类型。硬编码枚举描述并不比以真实域对象命名类更不正确。有时是鱼。巴别鱼永远是“巴别鱼”。可以从本地化资源(用于全球化)中获取值,但您不必从数据库或外部文件中获取每一条信息。@Michael Earls-应用程序来来往往,但数据永远存在。如果将其放入数据库中,则可以从任意数量的应用程序中使用它@dcp-很好的观点。谢谢你的链接。这是非常有用的。很难根据OP中的示例文本进行这种评估。也许这只是他为了明确自己的观点而举的一个简单的例子,但实际上他会使用更适合这个解决方案的东西。我用它来表示cookie类型/名称。字典不是强打印的,所以对我来说这是一个坏主意。虽然有效,但令人难以置信slow@ceds-同意,但成本可能是值得的。在我们的案例中,只有极少数地方使用此功能。如果备份存储是数据库,则速度尤其慢。但是好处和用例是存在的。谢谢,这很有帮助。我更新了它,如果没有描述,则返回枚举的名称,如果descriptionAttribute为null,则返回type.GetEnumName(val)。@Laurie Dickinson-这是个好主意。谢谢分享。@David Storfer这可能不是个坏主意,不过我应该将它改为
First()
,并取消默认设置。我相信,由于它是一个枚举,我们几乎可以保证在这一点上有一个值。它不应该是空的。
string enumName = nameof(MyEnum.EnumVal1); // enumName will equal "EnumVal1"
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;
        }
    }
}