Enum.IsDefined 无法识别有效的枚举值

本文关键字:枚举 有效 识别 IsDefined Enum | 更新日期: 2023-09-27 18:30:29

我正在尝试修复代码崩溃。

Enum.IsDefined在此方法中返回"false",当它检查Item49

public static VocabularyEnum Status(Status currentStatus)
{
    if (Enum.IsDefined(typeof(VocabularyEnum), (VocabularyEnum)currentStatus))
        return (VocabularyEnum)currentStatus;
    else
        throw new ArgumentOutOfRangeException("currentStatus");
} 

以下是自动生成的词汇词典enum

[System.CodeDom.Compiler.GeneratedCodeAttribute("cxsc", "0.57.0.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(TypeName="voc.Status",         
                                           Namespace="http://somenamespace/opennamespace")]
public enum VocabularyEnum
{
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("1")]
    Item1,
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("2")]
    Item2,
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("3")]
    Item3,
    <...>
    /// <remarks/>
    [System.Xml.Serialization.XmlEnumAttribute("49")]
    Item49,
} 
if (Enum.IsDefined(typeof(VocabularyEnum), (int)currentStatus))

这是我的enum

public enum Status : byte
{
    [Description("Description for item1")]
    ReadableNameOne = 1,
    [Description("Description for item2")]
    ReadableNameTwo = 2,
    [Description("Description for item3")]
    ReadableNameThree = 3,
    <...>
    [Description("Description for item49")]
    ReadableNameFourtyNine = 49
}

我很困惑为什么它会这样做。有谁知道为什么会这样做和/或如何解决这个问题?

Enum.IsDefined 无法识别有效的枚举值

所有值都偏移 1。VocabularyEnum的值从 0 开始,而不是从 1 开始。因此,VocabularyEnum.Item49的值是 48,而不是 49。但是Status.ReadableNameFourtyNine的值是 49,因为这是您指定的。所以(VocabularyEnum)Status.ReadableNameFourtyNine不是VocabularyEnum的有效值......

首先,代码在任何情况下都无法"正确"工作。 即,如果我尝试使用"Status.ReadableNameOne",那么我会得到"Item2",我相信这也不是您想要的"Item1"结果。 第一个问题是您将"状态"的枚举实例转换为"词汇枚举"。 下一个问题是XmlEnumAttribute只是一个属性,而不是.Net枚举逻辑的"可操作"部分。

为了获得一个像我理解的那样工作的版本,需要获取当前状态参数的 int 值并找到具有匹配 XmlEnumAttribute 属性的词汇项。

下面的示例正是这种方法。 认为这是必要的是丑陋的,但在我的测试中它是完美无缺的。 警惕性能问题。

例如

public class Program
{
    static void Main(string[] args)
    {
        Debug.WriteLine(CheckStatus(Status.ReadableNameOne));
        Debug.WriteLine(CheckStatus(Status.ReadableNameFourtyNine));
    }
    public static VocabularyEnum CheckStatus(Status currentStatus)
    {
        var result = Enum.GetValues(typeof(VocabularyEnum)).Cast<object>().Where(e =>
            ((XmlEnumAttribute)typeof(VocabularyEnum)
                    .GetMember(e.ToString())[0]
                    .GetCustomAttributes(typeof(XmlEnumAttribute), false)[0])
                    .Name == ((int)currentStatus).ToString()).FirstOrDefault();
        if (result != null)
            return (VocabularyEnum)result;
        else
            throw new ArgumentOutOfRangeException("currentStatus");
    }
    [System.CodeDom.Compiler.GeneratedCodeAttribute("cxsc", "0.57.0.0")]
    [System.SerializableAttribute()]
    [System.Xml.Serialization.XmlTypeAttribute(TypeName = "voc.Status",
                                               Namespace = "http://somenamespace/opennamespace")]
    public enum VocabularyEnum
    {
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("1")]
        Item1,
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("2")]
        Item2,
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("3")]
        Item3,
        /// <remarks/>
        [System.Xml.Serialization.XmlEnumAttribute("49")]
        Item49,
    }
    public enum Status : byte
    {
        ReadableNameOne = 1,
        ReadableNameTwo = 2,
        ReadableNameThree = 3,
        ReadableNameFourtyNine = 49
    }
}