检查值是否在枚举范围内,而不使用 IsDefined

本文关键字:IsDefined 范围内 是否 枚举 检查 | 更新日期: 2023-09-27 18:31:27

还有一些关于如何转换枚举以及如果解析的值超出范围会发生什么问题,例如:

public enum SomeTypes
{
    SomeType1 = 1,
    SomeType2 = 2,
    SomeType3 = 3
}
public class SomeClass
{
    ...
    var inRange = (SomeTypes) 1;
    var outOfRange = (SomeTypes) 5;
    ...
}

超出范围不会产生任何错误。但是我发现很难的方法,如果你尝试序列化-反序列化一个值超出范围的枚举,你会遇到奇怪的错误。例如,我得到了类似的东西

"解析消息时出错或超出超时"

这让我一直在寻找其他原因,而不是枚举超出范围。

处理此问题的建议是通过Enum.IsDefined。这似乎工作得很好,但是msdn上有这个相当大胆的警告:

"不要使用 System.Enum.IsDefined(System.Type,System.Object) 进行枚举范围检查,因为它基于枚举的运行时类型,该类型可能会因版本而异。

所以,我的问题是,我们是否可以安全地使用 Enum.IsDefined,或者在不使用 Enum.IsDefined 的情况下检查枚举的值是否超出范围的正确方法是什么?

检查值是否在枚举范围内,而不使用 IsDefined

使用 Enum.GetValues()

public bool IsInRange(int value){
  var values = Enum.GetValues(typeof(SomeTypes)).Cast<int>().OrderBy(x => x);
  return value >= values.First() && value <= values.Last();
}

[编辑]

如果您想检查项目是否已定义,而不仅仅是检查它是否在范围内,您可以执行类似的操作:

public bool IsDefined(int value){
  var values = Enum.GetValues(typeof(SomeTypes)).Cast<int>().OrderBy(x => x);
  return values.Contains(value);
}

有一个更简单的选项:

int value;
bool isInRange = !string.IsNullOrEmpty(Enum.GetName(typeof(myEnumType), value));

我对对象做了类似的事情DataContract您必须使用 [EnumMember] 修饰列表中的项目,然后可以使用此方法获取枚举名称。所以你会知道值是否存在于枚举中 cos 返回他的枚举名称。

public static string GetEnumNameFromValue(System.Type typeEnum, string value)
        {
            FieldInfo[] fis = typeEnum.GetFields();
            foreach (FieldInfo fi in fis)
            {
                EnumMemberAttribute[] attributes = (EnumMemberAttribute[])fi.GetCustomAttributes(typeof(EnumMemberAttribute), false);
                if (attributes.Length > 0)
                {
                    if (string.Compare(attributes[0].Value, value, true) == 0)
                    {
                        return fi.Name;
                    }
                }
            }
            return null;
        }