Как назначить строковые значения для перечисления и использовать это значение в коммутаторе
В принципе в заголовок switch будет передан ряд заголовков, и мне нужно сравнить их со строковыми значениями перечисления. Но я не знаю, как это сделать правильно.
Кроме того, я не знаю, является ли это даже наилучшим подходом, поэтому, если у кого-нибудь есть идеи?
Например:
enum
{
doctor = "doctor",
mr = "mr",
mrs = "mrs"
}
а затем переключитесь на строковые значения, которые я им назначил.
Ответы
Ответ 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;
}
}
}