【问题标题】:Enum with Spaces .TryParse not working - C#带空格的枚举 .TryParse 不起作用 - C#
【发布时间】:2017-02-15 18:17:21
【问题描述】:

我有一种枚举类型,其中包含带有空格的项目

     public enum Enum1
    {
        [Description("Test1 Enum")]
        Test1Enum,
        [Description("Test2 Enum")]
        Test2Enum,
        [Description("Test3Enum")]
        Test3Enum, 
    }

   public void TestMethod(string testValue)
     {
        Enum1 stEnum;
        Enum.TryParse(testValue, out stEnum);
        switch (stEnum)
        {
            case ScriptQcConditonEnum.Test1Enum:
                Console.Log("Hi");
                break;
        }
      }

当我使用 Enum.TryParse(testValue, out stEnum) 时,它总是返回第一个元素。

 // Currently stEnum returns Test1Enum which is wrong
    Enum.TryParse("Test2 Enum", out stEnum) 

【问题讨论】:

  • testValue 中有什么内容?它查看值的名称,而不是描述。我的意思是你的枚举中没有空格。
  • TryParse 很可能返回 false,表示解析失败,而 stEnum 是默认值 0,即 TestEnum1。我不确定这个 DescriptionAttribute 是什么,但我认为 Enum.Parse/TryParse 方法对它没有任何作用。
  • @Brandon testValue 是字符串。例如:Test1 Enum ..ie 与我在 [Description] 属性中输入的值相同
  • 它不比较 Description 值。它看名字
  • 另外,如果使用 object.TryParse,请检查返回值(这就是为什么它是 Try)。 if (! Enum.TryParse(...) { ReportThatItFailed(); }

标签: c# .net oop enums


【解决方案1】:

您可以从 Enum 描述中解析 Enum,但您需要从描述中检索 Enum 值。请检查下面的示例,该示例从 Enum 描述中检索 Enum 值并根据需要对其进行解析。

来自枚举描述的枚举值:

public T GetValueFromDescription<T>(string description)
    {
        var type = typeof(T);
        if (!type.IsEnum) throw new InvalidOperationException();
        foreach (var field in type.GetFields())
        {
            var attribute = Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) as DescriptionAttribute;
            if (attribute != null)
            {
                if (attribute.Description == description)
                    return (T)field.GetValue(null);
            }
            else
            {
                if (field.Name == description)
                    return (T)field.GetValue(null);
            }
        }
        throw new ArgumentException("Not found.", "description");
        // or return default(T);
    }

解析示例:

Enum.TryParse(GetValueFromDescription<Enum1>("Test2 Enum").ToString(), out stEnum);

【讨论】:

    【解决方案2】:

    Enum.TryParse 尝试根据枚举值而不是描述来解析字符串。如果您的要求是根据描述进行解析,则需要使用反射来获取属性值。这个 SO 问题已经回答了如何做到这一点:Finding an enum value by its Description Attribute

    【讨论】:

    • ..除了反射之外还有其他选择来解决这个问题吗..或者像任何逻辑方法一样
    • 这取决于您的用例。您可以尝试Enum.TryParse(testValue.Replace(" ", string.Empty), out stEnum);,但只有在描述与您的示例中的空格以外的值相同时才会匹配。
    • 这对您解决问题有帮助吗?你在其他地方找到答案了吗?请标记有帮助的答案或添加您在其他地方找到的答案。谢谢。
    【解决方案3】:

    基于@csharpbd的思路,我想到了下面的做法。

    public static T ParseEnum<T>(string valueToParse)
    {
        // Check if it is an enumerated
        if (typeof(T).IsEnum)
        {
            // Go through all the enum
            foreach (T item in (T[])Enum.GetValues(typeof(T)))
            {
                System.Reflection.FieldInfo fieldInfo = item.GetType().GetField(item.ToString());
    
                // Before doing anything else we check that the name match
                if (fieldInfo.Name == valueToParse)
                {
                    return item;
                }
    
                DescriptionAttribute[] descriptionAttributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
    
                // Check if the description matches what we are looking for.
                if (descriptionAttributes.Length > 0 && descriptionAttributes[0].Description == valueToParse)
                {
                    return item;
                }
            }
    
            throw new ArgumentException("Enum cannot be found", valueToParse);
        }
        else
        {
            throw new InvalidOperationException("The object is not an enum");
        }
    }
    

    所以,你可以叫他:

    Enum1 stEnum = ParseEnum<Enum1>(testValue);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2012-01-13
      • 1970-01-01
      • 2016-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多