枚举的扩展方法,而不是枚举的实例

Jam*_*zor 44 c# extension-methods enums

我对我的事情进行了枚举,如下:

public enum Things
{
   OneThing,
   AnotherThing
}
Run Code Online (Sandbox Code Playgroud)

我想为这个枚举编写一个扩展方法(类似于Prize的答案)但是该方法适用于枚举实例,ala

Things thing; var list = thing.ToSelectList();
Run Code Online (Sandbox Code Playgroud)

我希望它能用于实际的枚举:

var list = Things.ToSelectList();
Run Code Online (Sandbox Code Playgroud)

我可以这样做

var list = default(Things).ToSelectList();
Run Code Online (Sandbox Code Playgroud)

但我不喜欢那样:)

我已经接近以下扩展方法:

public static SelectList ToSelectList(this Type type)
{
   if (type.IsEnum)
   {
      var values = from Enum e in Enum.GetValues(type)
                   select new { ID = e, Name = e.ToString() };
      return new SelectList(values, "Id", "Name");
   }
   else
   {
      return null;
   }
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

var list = typeof(Things).ToSelectList();
Run Code Online (Sandbox Code Playgroud)

我们可以做得更好吗?

Aar*_*ght 72

扩展方法仅适用于实例,因此无法完成,但通过一些精心选择的类/方法名称和泛型,您可以生成看起来同样好的结果:

public class SelectList
{
    // Normal SelectList properties/methods go here

    public static SelectList Of<T>()
    {
        Type t = typeof(T);
        if (t.IsEnum)
        {
            var values = from Enum e in Enum.GetValues(type)
                         select new { ID = e, Name = e.ToString() };
            return new SelectList(values, "Id", "Name");
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以得到这样的选择列表:

var list = SelectList.Of<Things>();
Run Code Online (Sandbox Code Playgroud)

国际海事组织比这读得好多了Things.ToSelectList().

  • @Iucounu:我完全理解它,它是来自石器时代Java的"类型安全枚举"模式,然后语言设计师才最终意识到并实现了实际的枚举.你的解决方案*不是一个解决方案,因为问题是关于实际的枚举,除此之外,对其他答案的评论几乎不是宣传你自己的适当媒介. (4认同)
  • 这真是太棒了,当我读到它时,我大声笑了起来.我非常专注于为一个选择列表制作一个枚举,我从来没有想过要这样做. (3认同)
  • @Iucounu:缺点是......它不是一个枚举.您不会获得范围检查,数字表示,简单数据库存储,自动字符串转换或枚举的任何其他好处.鉴于这些缺点并没有真正的好处,我想不出你为什么要这样做. (3认同)

SLa*_*aks 5

没有.

你能做的最好的事情是把它放在静态类上,如下所示:

public static class ThingsUtils { 
    public static SelectList ToSelectList() { ... }
}
Run Code Online (Sandbox Code Playgroud)


qqb*_*enq 5

Aaronaught 的回答真的很棒,基于此我做了以下实现:

public class SelectList
{
    public static IEnumerable<Enum> Of<T>() where T : struct, IConvertible
    {
        Type t = typeof(T);
        if (t.IsEnum)
        {
            return Enum.GetValues(t).Cast<Enum>();
        }
        throw new ArgumentException("<T> must be an enumerated type.");
    }
}
Run Code Online (Sandbox Code Playgroud)

在我看来,它更安全一些,因为您几乎可以仅使用枚举来调用它,当然,如果您想要一个无异常版本,您可以简单地返回 null 而不是抛出。