首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么将int转换为无效枚举值不抛出异常?

为什么将int转换为无效枚举值不抛出异常?
EN

Stack Overflow用户
提问于 2011-06-20 23:38:20
回答 1查看 46.6K关注 0票数 137

如果我有一个像这样的枚举:

enum Beer
{
    Bud = 10,
    Stella = 20,
    Unknown
}

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

例如,下面的代码没有抛出异常,它将'50‘输出到控制台:

int i = 50;
var b = (Beer) i;

Console.WriteLine(b.ToString());

我发现这个strange...can有人澄清了吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-20 23:41:17

摘自Confusion with parsing an Enum

这是创建.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.

编辑

除了上面给出的解释之外,您还必须认识到,.NET版本的枚举遵循的是一种更受C语言启发的模式。这使得可以使用二进制模式来确定特定“标志”在枚举值中是否有效的"Bit Flag" enums成为可能。如果你必须定义每种可能的标志组合(例如MondayAndTuesdayMondayAndWednesdayAndThursday),这些将是非常繁琐的。因此,能够使用未定义的枚举值是非常方便的。当您想要在不利用这些技巧的枚举类型上执行快速失败行为时,只需要做一些额外的工作。

票数 88
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6413804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档