Подтвердить что ты не робот

Как назначить строковые значения для перечисления и использовать это значение в коммутаторе

В принципе в заголовок switch будет передан ряд заголовков, и мне нужно сравнить их со строковыми значениями перечисления. Но я не знаю, как это сделать правильно.

Кроме того, я не знаю, является ли это даже наилучшим подходом, поэтому, если у кого-нибудь есть идеи?

Например:

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

а затем переключитесь на строковые значения, которые я им назначил.

4b9b3361

Ответ 1

У вас не может быть enum с базовым типом string. Базовым типом может быть любой целочисленный тип, кроме 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
}

Ответ 2

Я обнаружил, что лучший способ сделать это - использовать атрибут System.ComponentModel.DescriptionAttribute в значениях перечисления.

Вот пример:

using System.ComponentModel;

public enum ActionCode
{
    [Description("E")]
    Edit,
    [Description("D")]
    Delete,
    [Description("R")]
    Restore
}

Затем, чтобы использовать его, создайте метод расширения для статического класса следующим образом:

Изменение: я переписал метод, чтобы включить отличное предложение от Лори Дикинсон так, чтобы метод возвращал имя значения перечисления, когда нет атрибута описания. Я также переработал метод, чтобы попытаться улучшить функциональность. Теперь он работает для всех Enums без использования 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".

Вот еще один пример Enum:

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"

Я хотел пойти дальше и опубликовать общий метод, так как он гораздо полезнее. Это предотвращает необходимость написания собственного расширения для всех ваших перечислений.

Ответ 3

Это не та вещь, которая должна быть жестко закодирована. Он должен управляться данными, возможно, считываться из внешнего файла или базы данных. Вы можете сохранить их в Dictionary и использовать ключи для управления своей логикой.

Ответ 4

Перечисления не могут быть строкового типа.

Утвержденные типы для перечисления являются байтами, sbyte, short, ushort, int, uint, long или ulong.

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

Ответ 5

Enum может иметь только интегральные базовые типы (кроме char). Поэтому вы не можете делать то, что хотите, по крайней мере, напрямую.

Однако вы можете перевести строку, имеющую тип перечисления:

EnumType eVal = (EnumType)Enum.Parse(typeof(EnumType), strValue);

switch(eVal)
{
    case EnumType.doctor:/*...*/; break;
    case EnumType.mr: /*...*/; break;
}

Ответ 6

Я считаю, что стандартный способ сделать это - использовать статический класс со свойствами readonly string, которые возвращают требуемое значение.

Ответ 7

Я хотел добавить еще один ответ для тех, кто использует С# 6 или выше.

Если вы хотите получить имя значения Enum, вы можете использовать новый метод nameof(), введенный в С# 6.

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

Хотя это может показаться излишним на первый взгляд (почему бы не просто установить значение строки в "EnumVal1" для начала?), это даст вам возможность проверить время компиляции, чтобы убедиться, что значение действительно. Итак, если вы когда-либо измените имя значения перечисления и забудьте сообщить своей среде IDE, чтобы найти и заменить все ссылки, она не будет компилироваться, пока вы их не исправите.

Ответ 8

Почему бы не использовать только чистые перечисления и переключатели?

enum Prefix
{
    doctor,
    mr,
    mrs
}

Тогда вы можете использовать это как

string case = "doctor";

switch ((Prefix)Enum.Parse(typeof(Prefix), "doctor"))
{
    case Prefix.doctor:
        ...
        break;
    ...
    default:
        break;
}

Ответ 9

Прочитайте этот учебник, чтобы понять, как работают перечисления. Существуют примеры операторов switch.

Ответ 10

Просто делюсь своим решением. Загрузив пакет nuget Extension.MV, можно получить метод для получения строки из описания Enum

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