【问题标题】:Searching a enum description containing a slash搜索包含斜杠的枚举描述
【发布时间】:2014-11-24 15:29:21
【问题描述】:

为了尽量简短,我创建了以下枚举

public enum Frequency
{
    [Description("Monthly")]
    Monthly,
    [Description("Quarterly")]
    Quarterly,
    [Description("N/A")]
    NA
}

然后我有一个使用相同描述字符串的组合框。

当我选择一个新选项时,特别是“N/A”选项,它无法正确读取。

我用来根据传入的字符串搜索正确枚举的代码是...

/// Returns an enum of the specified type that matches the string value passed in. Note this does ignore case
<param name="value">The string value.</param>        
public static TEnum GetEnum<TEnum>(string value)
{
    if (string.IsNullOrEmpty(value))
    {
        // Default not set value name
        value = "None";
    }
     return (TEnum)System.Enum.Parse(typeof(TEnum), value.Replace(" ", string.Empty), true);
}

所以当 value = "N/A" 时,我得到以下错误..

"An unhandled exception of type 'System.ArgumentException' occurred in mscorlib.dll"

附加信息:未找到请求的值 'N/A'。"

我似乎无法理解为什么会发生这种情况。还有另一个预先存在的组合框,其中 decriction 还包含一个“/”字符,并且会发生相同的错误。所以这似乎不是我做错了什么,而只是枚举字符串检查的行为。

任何有关这导致问题的原因的见解将不胜感激。 :) 谢谢!

编辑: 更多信息..

所以这是触发枚举搜索的代码..

if (this.FrequencyCombo.SelectedItem != null && !this.FrequencyCombo.SelectedItem.Equals(Utilities.GetDescription(currentLoan.Frequency)))
        {
            currentLoan.Frequency = Utilities.GetEnum<Frequency>(this.FrequencyCombo.SelectedItem.ToString());
        }

【问题讨论】:

  • 检查的是名称 (NA),而不是描述 (N/A)。
  • 显示的代码中没有任何内容表明完全使用了描述。
  • 为什么你没有让文本使用Description,但是你的组合值是枚举值。
  • 感谢到目前为止的 cmets!我已经添加了一段额外的代码来做'GetEnum'检查。也许这有帮助。当我在调试器中时,我到达行 return (TEnum)System.Enum.Parse(typeof(TEnum), value.Replace(" ", string.Empty), true);当我将鼠标悬停在“值”变量上时,它肯定显示为“N/A”。所以你的意思是希望通过“NA”,而不是“N/A”?

标签: c# enums


【解决方案1】:

将您的方法替换为以下内容,您正在尝试将描述与值匹配:

    /// <summary>
    /// Gets the Enum from a matching description value
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="description"></param>
    /// <returns></returns>
    public static 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("Enum description not found.", "Description");            
    }

【讨论】:

    【解决方案2】:

    Enum.Parse 接受一个字符串参数,表示枚举值的名称,而不是描述,即Enum.ToString() 返回的内容。您需要一种通过描述查找枚举值的方法,如下所示:

    public static TEnum GetEnumByDescription<TEnum>(string desc) where TEnum : struct
    {
        if(string.IsNullOrEmpty(desc))
        {
            return default(TEnum);
        }
        foreach(var field in typeof(TEnum).GetFields(BindingFlags.Static | BindingFlags.Public))
        {
            var attr = (DescriptionAttribute)field.GetCustomAttribute(typeof(DescriptionAttribute));
            if(attr != null && attr.Description == desc)
            {
                return (TEnum)field.GetValue(null);
            }
        }
        return default(TEnum);
    }
    

    【讨论】:

      【解决方案3】:

      这样的事情就可以了。它列出所有成员,获取他们的描述并将它们与您要查找的字符串进行比较。

          public static T GetByDescription<T>(string description) {
              return Enum.GetValues(typeof(T))
                  .OfType<T>()
                  .First(f => {
                      var memberInfo = typeof(T).GetMember(f.ToString());
                      var desc = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                      return desc.Length == 1 && ((DescriptionAttribute)desc[0]).Description.Equals(description, StringComparison.InvariantCultureIgnoreCase);
                  });
          }
      

      使用方法:

      GetByDescription<Frequency>("Monthly");
      GetByDescription<Frequency>("N/A");
      

      相关:Getting attributes of Enum's value

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-01
        • 2015-12-30
        • 2015-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多