Перечисление из строки, int и т.д.
Используя метод расширения, мы можем создавать методы для преобразования перечисления в другой тип данных типа string, int путем создания методов расширения ToInt()
, ToString()
и т.д. для перечисления.
Интересно, как реализовать другой способ, например? FromInt(int)
, FromString(string)
и т.д. Насколько я знаю, я не могу создать метод MyEnum.FromInt()
(статического) расширения. Итак, каковы возможные подходы для этого?
Ответы
Ответ 1
Я бы не стал загрязнять int или string с помощью методов расширения для перечислений, вместо этого мог бы быть установлен старый старомодный статический вспомогательный класс.
public static class EnumHelper
{
public static T FromInt<T>(int value)
{
return (T)value;
}
public static T FromString<T>(string value)
{
return (T) Enum.Parse(typeof(T),value);
}
}
Ответ 2
Вам действительно нужны эти методы расширения?
MyEnum fromInt = (MyEnum)someIntValue;
MyEnum fromString = (MyEnum)Enum.Parse(typeof(MyEnum), someStringValue, true);
int intFromEnum = (int)MyEnum.SomeValue;
string stringFromEnum = MyEnum.SomeValue.ToString();
Ответ 3
В противном случае возможно... наоборот:) Расширьте int и string с помощью общих методов расширения, которые будут принимать в качестве параметра типа тип перечисления:
public static TEnum ToEnum<TEnum>(this int val)
{
return (TEnum) System.Enum.ToObject(typeof(TEnum), val);
}
public static TEnum ToEnum<TEnum>(this string val)
{
return (TEnum) System.Enum.Parse(typeof(TEnum), val);
}
Использование:
var redFromInt = 141.ToEnum<System.Drawing.KnownColor>();
var redFromString = "Red".ToEnum<System.Drawing.KnownColor>();
К сожалению, нет общего ограничения для Enums, поэтому мы должны проверять тип TEnum во время выполнения; для упрощения мы оставим эту проверку методам Enum.ToObject
и Enum.Parse
.
Ответ 4
почему вы хотите использовать метод ExtInstion FromInt и просто его лить?
MyEnum fromInt;
if(Enum.IsDefined(typeof(MyEnum), intvalue))
{
fromInt = (MyEnum) intvalue;
}
else
{
//not valid
}
альтернативно, для строк вы можете использовать Enum.TryParse
MyEnum fromString;
if (Enum.TryParse<MyEnum>(stringvalue, out fromString))
{
//succeeded
}
else
{
//not valid
}
Ответ 5
Другой подход (для строковой части вашего вопроса):
/// <summary>
/// Static class for generic parsing of string to enum
/// </summary>
/// <typeparam name="T">Type of the enum to be parsed to</typeparam>
public static class Enum<T>
{
/// <summary>
/// Parses the specified value from string to the given Enum type.
/// </summary>
/// <param name="value">The value.</param>
/// <returns></returns>
public static T Parse(string value)
{
//Null check
if(value == null) throw new ArgumentNullException("value");
//Empty string check
value = value.Trim();
if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
//Not enum check
Type t = typeof(T);
if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "T");
return (T)Enum.Parse(typeof(T), value);
}
}
(Частично вдохновлено: http://devlicious.com/blogs/christopher_bennage/archive/2007/09/13/my-new-little-friend-enum-lt-t-gt.aspx)
Ответ 6
Вы можете сделать:
public static class EnumExtensions
{
public static Enum FromInt32(this Enum obj, Int32 value)
{
return (Enum)((Object)(value));
}
public static Enum FromString(this Enum obj, String value)
{
return (Enum)Enum.Parse(obj.GetType(), value);
}
}
Или:
public static class Int32Extensions
{
public static Enum ToEnum(this Int32 obj)
{
return (Enum)((Object)(obj));
}
}
public static class StringExtensions
{
public static Enum ToEnum(this Enum obj, String value)
{
return (Enum)Enum.Parse(obj.GetType(), value);
}
}
Ответ 7
Вы можете либо сделать методы расширения для int и string.
Или сделайте статический метод для другого статического класса. Возможно, что-то вроде EnumHelper.FromInt(int).
Но я бы поставил один вопрос: зачем вы хотите преобразовать в строку или int? Это не то, как вы нормально работаете с перечисляемыми, за исключением, может быть, сериализации. Но это должно быть связано с какой-то инфраструктурой, а не с вашим собственным кодом.