在不使用IsDefined的情况下检查值是否在Enum范围内

时间:2014-11-21 11:02:09

标签: c# enums

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

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的情况下检查枚举值是否超出范围的正确方法是什么?

3 个答案:

答案 0 :(得分:1)

使用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);
}

答案 1 :(得分:0)

我对对象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;
        }

答案 2 :(得分:0)

有一个简单的选项:

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