栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

从混淆中获取枚举

这是创建.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版本遵循的是比C语言更受C语言启发的模式。这样就可以拥有“位标志”枚举,该枚举可以使用二进制模式来确定某个特定“标志”在枚举值中是否处于活动状态。如果你必须定义标志的每一个可能的组合(即

MondayAndTuesday
MondayAndWednesdayAndThursday
),这将是非常乏味的。因此,具有使用未定义的枚举值的能力非常方便。当您想要对不利用这些技巧的枚举类型执行快速失败操作时,只需要做一些额外的工作即可。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/506779.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号