Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
375 views
in Technique[技术] by (71.8m points)

c# - 创建将T约束为枚举的泛型方法(Create Generic method constraining T to an Enum)

I'm building a function to extend the Enum.Parse concept that

(我正在构建一个函数来扩展Enum.Parse概念,)

  • Allows a default value to be parsed in case that an Enum value is not found

    (如果找不到Enum值,则允许解析默认值)

  • Is case insensitive

    (不区分大小写)

So I wrote the following:

(所以我写了以下内容:)

public static T GetEnumFromString<T>(string value, T defaultValue) where T : Enum
{
    if (string.IsNullOrEmpty(value)) return defaultValue;
    foreach (T item in Enum.GetValues(typeof(T)))
    {
        if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
    }
    return defaultValue;
}

I am getting a Error Constraint cannot be special class System.Enum .

(我收到了一个错误约束,它不能是System.Enum特殊类。)

Fair enough, but is there a workaround to allow a Generic Enum, or am I going to have to mimic the Parse function and pass a type as an attribute, which forces the ugly boxing requirement to your code.

(足够公平,但是有一种允许通用枚举的解决方法,还是我必须模仿Parse函数并将类型作为属性传递,这迫使对代码使用难看的装箱要求。)

EDIT All suggestions below have been greatly appreciated, thanks.

(编辑谢谢所有下面的建议。)

Have settled on (I've left the loop to maintain case insensitivity - I am using this when parsing XML)

(已经解决(我离开了循环以保持不区分大小写-解析XML时正在使用它))

public static class EnumUtils
{
    public static T ParseEnum<T>(string value, T defaultValue) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum) throw new ArgumentException("T must be an enumerated type");
        if (string.IsNullOrEmpty(value)) return defaultValue;

        foreach (T item in Enum.GetValues(typeof(T)))
        {
            if (item.ToString().ToLower().Equals(value.Trim().ToLower())) return item;
        }
        return defaultValue;
    }
}

EDIT: (16th Feb 2015) Julien Lebosquain has recently posted a compiler enforced type-safe generic solution in MSIL or F# below, which is well worth a look, and an upvote.

(编辑: (2015年2月16日)Julien Lebosquain最近在下面的MSIL或F#中发布了由编译器强制执行的类型安全的通用解决方案 ,这很值得一看,并值得一提。)

I will remove this edit if the solution bubbles further up the page.

(如果解决方案在页面上冒泡,我将删除此编辑。)

  ask by johnc translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since Enum Type implements IConvertible interface, a better implementation should be something like this:

(由于Enum Type实现IConvertible接口,因此更好的实现应如下所示:)

public T GetEnumFromString<T>(string value) where T : struct, IConvertible
{
   if (!typeof(T).IsEnum) 
   {
      throw new ArgumentException("T must be an enumerated type");
   }

   //...
}

This will still permit passing of value types implementing IConvertible .

(这仍然允许传递实现IConvertible的值类型。)

The chances are rare though.

(机会虽然很少。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...