扩展方法得到任何枚举的价值观 [英] Extension Method to Get the Values of Any Enum

查看:122
本文介绍了扩展方法得到任何枚举的价值观的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在试图创建一个扩展方法,这将在任何枚举工作,返回其值



而不是这样做的:

  Enum.GetValues(typeof运算(BiasCode))演员LT; BiasCode>()

这将是很好的做到这一点:

 新BiasCode( ).Values()

它甚至会更好没有的新的的,但这是另外一个问题。



我有一个 .NET小提琴,有一个解决方案,它接近(如下代码所示)。这段代码的问题是,扩展方法将返回列表< INT> 。我想拥有它返回枚举值本身的列表。返回列表与LT; INT> 并不可怕;它只是意味着我必须投的结果。



它甚至有可能做到这一点?我试图使扩展方法通用的,但遇到了问题。这是接近我能得到:

 使用系统; 
使用System.Linq的;
使用System.Collections.Generic;

公共类节目
{
公共静态无效的主要()
{
的foreach(INT新BiasCode biasCode()。值())
{
DisplayEnum((biasCode)biasCode);
}
}

公共静态无效DisplayEnum(BiasCode biasCode)
{
Console.WriteLine(biasCode);
}
}

公共枚举BiasCode
{
未知,
OC,
MPP
}

公共静态类EnumExtensions
{
公共静态列表< INT>值(此枚举theEnum)
{
变种enumValues =新的List< INT>();
的foreach(在Enum.GetValues诠释enumValue(theEnum.GetType()))
{
enumValues.Add(enumValue);
}

返回enumValues;
}
}


解决方案

您可以返回适当的枚举类型(使用反射创建)的实例,但它的静态类型不能为列表< EnumType> 。这将需要 EnumType 来是该方法的一个一般类型参数,但随后的类型将必须被限制为仅枚举类型和that是不可能在C#中



不过,你可以在实践中足够接近(并添加运行时检查,以最糟糕的),这样你可以编写工作原理是这样的方法:

 公共静态的IEnumerable< TEnum>价值和LT; TEnum>()
式TEnum:结构,IComparable的,IFormattable,IConvertible
{
VAR enumType = typeof运算(TEnum);

//可选运行时检查完整性
如果(enumType.IsEnum!)
{
抛出新的ArgumentException();
}

返回Enum.GetValues(enumType).Cast< TEnum>();
}



您可以用

调用

  VAR值=价值< BiasCode>(); 



我所做的方法返回的IEnumerable< TEnum> 而不是为额外的LINQ-Y的味道的清单,但你可以在平凡的返回值返回与 .ToList一个真正的list()


I've been trying to create an extension method, that would work on any enum, to return its values.

Instead of doing this:

Enum.GetValues(typeof(BiasCode)).Cast<BiasCode>()

It would be nice to do this:

new BiasCode().Values()

It would even be better without new, but that's another issue.

I have a .NET fiddle that has a solution that's close (code shown below). The problem with this code is that the extension method is returning List<int>. I would like to have it return a list of the enum values itself. Returning List<int> isn't terrible; it just means I have to cast the result.

Is it even possible to do this? I tried making the extension method generic, but ran into problems. This is as close as I was able to get:

using System;
using System.Linq;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        foreach (int biasCode in new BiasCode().Values())
        {
            DisplayEnum((BiasCode)biasCode);
        }
    }

    public static void DisplayEnum(BiasCode biasCode)
    {
        Console.WriteLine(biasCode);    
    }
}

public enum BiasCode
{
    Unknown,
    OC,
    MPP
}

public static class EnumExtensions
{
    public static List<int> Values(this Enum theEnum)
    {
        var enumValues = new List<int>();
        foreach (int enumValue in Enum.GetValues(theEnum.GetType()))
        {
            enumValues.Add(enumValue);
        }

        return enumValues;
    }
}

解决方案

You can return an instance of the appropriate enum type (created using reflection), but its static type cannot be List<EnumType>. That would require EnumType to be a generic type parameter of the method, but then the type would have to be constrained to only enum types and that is not possible in C#.

However, you can get close enough in practice (and add runtime checks to top it off) so you can write a method that works like this:

public static IEnumerable<TEnum> Values<TEnum>()
where TEnum : struct,  IComparable, IFormattable, IConvertible
{
    var enumType = typeof(TEnum);

    // Optional runtime check for completeness    
    if(!enumType.IsEnum)
    {
        throw new ArgumentException();
    }

    return Enum.GetValues(enumType).Cast<TEnum>();
}

which you can invoke with

var values = Values<BiasCode>();

I have made the method return IEnumerable<TEnum> instead of a list for the extra LINQ-y flavor, but you can trivially return a real list with .ToList() on the return value.

这篇关于扩展方法得到任何枚举的价值观的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆