에서 촬영 열거 구문 분석과 혼란
이것은 .NET을 만든 사람들의 결정이었습니다. 열거가 (다른 값 유형에 의해 백업됩니다 int, short,byte 실제로 그 값 유형에 대한 유효 값을 가질 수 있도록, 등)합니다.
나는 개인적으로 이것이 작동하는 방식을 좋아하지 않으므로 일련의 유틸리티 방법을 만들었습니다.
/// <summary>
/// Utility methods for enum values. This static type will fail to initialize
/// (throwing a <see cref="TypeInitializationException"/>) if
/// you try to provide a value that is not an enum.
/// </summary>
/// <typeparam name="T">An enum type. </typeparam>
public static class EnumUtil<T>
where T : struct, IConvertible // Try to get as much of a static check as we can.
{
// The .NET framework doesn't provide a compile-checked
// way to ensure that a type is an enum, so we have to check when the type
// is statically invoked.
static EnumUtil()
{
// Throw Exception on static initialization if the given type isn't an enum.
Require.That(typeof (T).IsEnum, () => typeof(T).FullName + " is not an enum type.");
}
/// <summary>
/// In the .NET Framework, objects can be cast to enum values which are not
/// defined for their type. This method provides a simple fail-fast check
/// that the enum value is defined, and creates a cast at the same time.
/// Cast the given value as the given enum type.
/// Throw an exception if the value is not defined for the given enum type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="enumValue"></param>
/// <exception cref="InvalidCastException">
/// If the given value is not a defined value of the enum type.
/// </exception>
/// <returns></returns>
public static T DefinedCast(object enumValue)
{
if (!System.Enum.IsDefined(typeof(T), enumValue))
throw new InvalidCastException(enumValue + " is not a defined value for enum type " +
typeof (T).FullName);
return (T) enumValue;
}
/// <summary>
///
/// </summary>
/// <param name="enumValue"></param>
/// <returns></returns>
public static T Parse(string enumValue)
{
var parsedValue = (T)System.Enum.Parse(typeof (T), enumValue);
//Require that the parsed value is defined
Require.That(parsedValue.IsDefined(),
() => new ArgumentException(string.Format("{0} is not a defined value for enum type {1}",
enumValue, typeof(T).FullName)));
return parsedValue;
}
public static bool IsDefined(T enumValue)
{
return System.Enum.IsDefined(typeof (T), enumValue);
}
}
public static class EnumExtensions
{
public static bool IsDefined<T>(this T enumValue)
where T : struct, IConvertible
{
return EnumUtil<T>.IsDefined(enumValue);
}
}
이렇게 말할 수 있습니다.
if(!sEnum.IsDefined()) throw new Exception(...);
... 또는 :
EnumUtil<Stooge>.Parse(s); // throws an exception if s is not a defined value.
편집하다
위에 제공된 설명 외에도 Enum의 .NET 버전은 Java에서 영감을받은 패턴보다 C에서 영감을받은 패턴을 따릅니다. 이렇게하면 이진 패턴을 사용하여 특정 "플래그"가 열거 형 값에서 활성 상태인지 여부를 확인할 수 있는 "비트 플래그"열거 형 을 가질 수 있습니다. 가능한 모든 플래그 조합 (예 : MondayAndTuesday, MondayAndWednesdayAndThursday) 을 정의해야한다면 매우 지루할 것입니다. 따라서 정의되지 않은 열거 형 값을 사용할 수있는 능력이 있으면 정말 편리 할 수 있습니다. 이러한 종류의 트릭을 활용하지 않는 enum 유형에 대한 빠른 실패 동작을 원할 때 약간의 추가 작업이 필요합니다.