У меня есть следующее перечисление:
public enum Urgency {
VeryHigh = 1,
High = 2,
Routine = 4
}
Я могу получить перечислить «значение» в виде строки следующим образом:
((int)Urgency.Routine).ToString() // returns "4"
Примечание: это отличается от:
Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine // returns 4
Есть ли способ, которым я могу создать класс расширения или класс статического utliity, который обеспечил бы некоторый синтаксический сахар? :)
Вы должны просто иметь возможность использовать перегрузки метода Enums ToString, чтобы передать ему строку формата, это распечатает значение перечисления в виде строки.
public static class Program
{
static void Main(string[] args)
{
var val = Urgency.High;
Console.WriteLine(val.ToString("D"));
}
}
public enum Urgency
{
VeryHigh = 1,
High = 2,
Low = 4
}
Для достижения более "человекочитаемых" описаний для перечислений (например, "Very High" вместо "VeryHigh" в вашем примере) я украсил значения перечисления атрибутом следующим образом:
public enum MeasurementType
{
Each,
[DisplayText("Lineal Metres")]
LinealMetre,
[DisplayText("Square Metres")]
SquareMetre,
[DisplayText("Cubic Metres")]
CubicMetre,
[DisplayText("Per 1000")]
Per1000,
Other
}
public class DisplayText : Attribute
{
public DisplayText(string Text)
{
this.text = Text;
}
private string text;
public string Text
{
get { return text; }
set { text = value; }
}
}
Затем, использовал метод расширения следующим образом:
public static string ToDescription(this Enum en)
{
Type type = en.GetType();
MemberInfo[] memInfo = type.GetMember(en.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(
typeof(DisplayText),
false);
if (attrs != null && attrs.Length > 0)
return ((DisplayText)attrs[0]).Text;
}
return en.ToString();
}
Затем вы можете просто вызвать
myEnum.ToDescription()для отображения вашего перечисления в виде более читаемого текста.
Если вы хотите просто работать с этим перечислением, используйте решение Марка Байера.
Для более общего решения:
public static string NumberString(this Enum enVal)
{
return Convert.ToDecimal(enVal).ToString("0");
}
Преобразование в десятичную систему означает, что вам не нужно явно работать с 8 различными допустимыми базовыми интегральными типами, поскольку все они без потерь преобразуются в десятичную систему, но не друг в друга (ulong и long не преобразуются без потерь друг в друга, но оба могут работать со всеми остальными). Это, вероятно, будет быстрее (особенно если вы хорошо выберете порядок сравнения), но гораздо более многословным при относительно небольшом выигрыше.
Edit:
Вышеприведенное не так хорошо, как у Франкентоша, однако, Франкентош увидел через вопрос настоящую проблему и решил ее очень красноречиво.
Как насчет небольшого размышления? Должно работать со всеми базовыми типами.
public static class EnumTools
{
public static string ToRawValueString(this Enum e)
{
return e
.GetType()
.GetFields(BindingFlags.Public | BindingFlags.Static)
.First(f => f.Name==e.ToString())
.GetRawConstantValue()
.ToString();
}
}
Then:
Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"
Отличный материал ... Теперь я добавил метод расширения в свой проект
public static class EnumExtensions
{
public static string NumberString(this Enum enVal)
{
return enVal.ToString("D");
}
}
Теперь я могу получить значение int - как строку - вызвав Urgency.Routine.NumberString();
Спасибо Frankentosh и Jon :)
Вы можете написать метод расширения для вашего конкретного типа:
public static class UrgencyExtension
{
public static string ToIntegerString(this Urgency u)
{
return ((int)u).ToString();
}
}
Используйте следующим образом:
Urgency u = Urgency.Routine;
string s = u.ToIntegerString();
Если вы хотите, вы можете заставить метод расширения работать для всех перечислений:
public static string ToValueString(this Enum enumValue)
{
if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
return ((int)(object)enumValue).ToString();
else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
return ((byte)(object)enumValue).ToString();
...
}