С# Кастинг с объектами в Enums
Этот вопрос связан с литьем перечислений в общих методах
Учитывая перечисление
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
Я могу создать экземпляр моего перечисления достаточно просто
short val = 4;
Crustaceans crusty = (Crustaceans) val;
Однако, если
short val = 4;
object obj = (object) val;
Crustaceans crusty = (Crustaceans)obj;
исключение для выполнения запускается, пытаясь выполнить инициализацию crusty.
Может ли кто-нибудь объяснить, почему это происходит, и почему это не является законным делать такую вещь.
Не то, чтобы я действительно хотел это сделать, но я решаю проблему, пытаясь получить что-то подобное с дженериками, и эффективно это то, что происходит под обложками. то есть.
public T dosomething<T>(short val) where T : new()
{
T result = (T)(object) val;
return result;
}
Итак, что я пытаюсь сделать, это иметь общую функцию, которая работает с перечислениями и не-перечислениями (не так критична, но будет приятной), которая может быть установлена на короткое значение, не вызывая исключения и фактически инициализируя правильную значение перечисления.
Ответы
Ответ 1
Что-то вроде этого возможно поможет вам:
public T dosomething<T>(object o)
{
T enumVal= (T)Enum.Parse(typeof(T), o.ToString());
return enumVal;
}
Но это будет работать только с перечислениями, по понятной причине использования Enum.Parse(..)
И используйте это, например:
object o = 4;
dosomething<Crustaceans>(o);
Это вернет Toad
в вашем случае.
Ответ 2
По умолчанию цифры перечисления имеют тип = int.
В вашем коде вы хотите указать значение, которое имеет короткий тип для типа перечисления. Для этого вам нужно задать короткий тип для значений перечисления. Это будет работать:
public enum Crustaceans : short // <--
{
Frog = 1,
Toad = 4
}
short @short = 1;
object @object = @short;
var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog
если вы не хотите изменять значения переменных enum по умолчанию
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
object @object = Crustaceans.Frog;
var @enum = (Crustaceans)@object; // @enum = Crustaceans.Frog
или
public enum Crustaceans
{
Frog = 1,
Toad = 4
}
int @integer= 1;
var @enum = (Crustaceans)@integer; // @enum = Crustaceans.Frog
Ответ 3
Бывают случаи, когда вы не можете использовать Generics (например, в конвертере WPF, когда вы получаете значение как object
).
В этом случае вы не можете использовать int
, потому что тип перечисления может не быть int
.
Это общий способ сделать это без Generics.
Пример указан внутри конвертера WPF, но код внутри является общим:
using System;
using System.Windows;
using System.Windows.Data;
.
.
.
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var enumType = value.GetType();
var underlyingType = Enum.GetUnderlyingType(enumType);
var numericValue = System.Convert.ChangeType(value, underlyingType);
return numericValue;
}