为什么将int强制转换为无效的枚举值不会引发异常?

如果我有这样的枚举:

enum Beer

{

Bud = 10,

Stella = 20,

Unknown

}

int将这些值之外的an强制转换为类型时,为什么不引发异常Beer

例如,以下代码不会引发异常,它会向控制台输出“ 50”:

int i = 50;

var b = (Beer) i;

Console.WriteLine(b.ToString());

我觉得这很奇怪…有人可以澄清吗?

回答:

从混淆中获取枚举

这是创建.NET的人员的决定。枚举被另一个值类型(备份intshortbyte,等),所以它实际上可以有一个有效期为那些值类型的任意值。

我个人不喜欢这种方式,所以我提出了一系列实用方法:

/// <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版本遵循的是比C语言更受C语言启发的模式。这样就可以拥有“位标志”枚举,该枚举可以使用二进制模式来确定某个特定“标志”在枚举值中是否处于活动状态。如果你必须定义标志的每一个可能的组合(即MondayAndTuesdayMondayAndWednesdayAndThursday),这将是非常乏味的。因此,具有使用未定义的枚举值的能力非常方便。当您想要对不利用这些技巧的枚举类型执行快速失败操作时,只需要做一些额外的工作即可。

以上是 为什么将int强制转换为无效的枚举值不会引发异常? 的全部内容, 来源链接: utcz.com/qa/411144.html

回到顶部