获取任何枚举值的扩展方法

Bob*_*orn 10 c# extension-methods enums

我一直在尝试创建一个扩展方法,它可以在任何枚举上工作,以返回它的值.

而不是这样做:

Enum.GetValues(typeof(BiasCode)).Cast<BiasCode>()
Run Code Online (Sandbox Code Playgroud)

这样做会很好:

new BiasCode().Values()
Run Code Online (Sandbox Code Playgroud)

如果没有新的话会更好,但这是另一个问题.

我有一个.NET小提琴,它有一个接近的解决方案(代码如下所示).此代码的问题是扩展方法正在返回List<int>.我想让它返回枚举值本身的列表.回归List<int>并不可怕; 这只是意味着我必须施展结果.

甚至可以这样做吗?我尝试使扩展方法通用,但遇到了问题.这与我能够得到的一样接近:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sel*_*enç 6

您可以像这样声明您的方法:

public static List<T> Values<T>() where T : struct
{
    var type = typeof(T);

    if(!type.IsEnum) return null; // or throw exception

    return Enum.GetValues(type).Cast<T>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话给它

Values<BiasCode>();
Run Code Online (Sandbox Code Playgroud)


Jon*_*Jon 5

您可以返回适当的枚举类型的实例(使用反射创建),但其静态类型不能为List<EnumType>。那将需要EnumType是该方法的通用类型参数,但随后必须将类型限制为仅枚举类型,而这在C#中是不可能的

但是,在实践中您可以足够接近(并添加运行时检查以使其结束),因此您可以编写一种如下所示的方法:

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>();
}
Run Code Online (Sandbox Code Playgroud)

您可以使用它来调用

var values = Values<BiasCode>();
Run Code Online (Sandbox Code Playgroud)

我已经使方法返回IEnumerable<TEnum>而不是具有额外的LINQ-y风格的列表,但是您可以使用.ToList()返回值简单地返回真实列表。


Bob*_*orn 5

我想知道我是否遗漏了一些东西,因为所有答案都使用通用方法作为解决方案的一部分。为什么不直接做这样的事情呢?

public static List<Enum> Values(this Enum theEnum)
{
    return Enum.GetValues(theEnum.GetType()).Cast<Enum>().ToList();
}
Run Code Online (Sandbox Code Playgroud)

小提琴在这里: https: //dotnetfiddle.net/FRDuvD

这样,该扩展方法将仅适用于枚举。使用泛型方法,扩展方法似乎可用于所有类型:

string someString = "x";
someString.Values();
Run Code Online (Sandbox Code Playgroud)

最好不要在编译时让 Values() 可用于字符串。