Я решил, что это невозможно сделать операции следующим образом (эквивалент) перечисления с помощью отражения - как класс Enum не имеет операторов, а также не излучаемый код выявят любые операторы:Получить интегральное значение штучной Enum
object boxedEnum = MyEnum.Flag1 | MyEnum.Flag2;
boxedEnum &= ~MyEnum.Flag2; // Remove the flag.
Так что я сейчас делаю следующее (эквивалент):
int boxedEnumValue = (int) boxedEnum;
boxedEnumValue &= ~MyEnum.Flag2;
boxedEnum = Enum.ToObject(boxedEnum.GetType(), boxedEnumValue);
который работает отлично, единственная проблема заключается в том, что эквивалентный код, чтобы превратить boxedEnum в целое число является:
int boxedEnumValue = int.Parse(Enum.Format(boxedEnum.GetType(), boxedEnum, "X"), System.Globalization.NumberStyles.HexNumber);
Который я уверен, что вы согласитесь, страшен и взломан.
Так что этот вопрос имеет два зубца. Было бы здорово, если бы кто-то мог доказать, что я ошибаюсь, и предоставить средства для выполнения двоичных операций с коробочными перечислениями - иначе любой способ избежать кругового движения будет оценен по достоинству.
Guffa дал мне то, что мне нужно, чтобы преобразовать перечисление в определенный тип. Я автор метода расширения, который делает суровое gritties:
/// <summary>
/// Gets the integral value of an enum.
/// </summary>
/// <param name="value">The enum to get the integral value of.</param>
/// <returns></returns>
public static T ToIntegral<T>(this object value)
{
if(object.ReferenceEquals(value, null))
throw new ArgumentNullException("value");
Type rootType = value.GetType();
if (!rootType.IsEnum)
throw new ArgumentOutOfRangeException("value", "value must be a boxed enum.");
Type t = Enum.GetUnderlyingType(rootType);
switch (t.Name.ToUpperInvariant())
{
case "SBYTE":
return (T)Convert.ChangeType((sbyte) value, typeof(T));
case "BYTE":
return (T) Convert.ChangeType((byte) value, typeof(T));
case "INT16":
return (T) Convert.ChangeType((Int16) value, typeof(T));
case "UINT16":
return (T) Convert.ChangeType((UInt16) value, typeof(T));
case "INT32":
return (T) Convert.ChangeType((Int32) value, typeof(T));
case "UINT32":
return (T) Convert.ChangeType((UInt32) value, typeof(T));
case "INT64":
return (T) Convert.ChangeType((Int64) value, typeof(T));
case "UINT64":
return (T) Convert.ChangeType((UInt64) value, typeof(T));
default:
throw new NotSupportedException();
}
}
К сожалению, я не могу. Это вспомогательный метод, который должен принимать любой вид перечисления. –
При условии, что базовый тип перечисления является int, вы можете просто распаковать его в int и поместить его в int. После этого boxed int может быть распакован в тип перечисления. – Guffa
@ Guffa вы гений! Можете ли вы отредактировать свой ответ, чтобы я мог его принять. –