Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extension Method to Get the Values of Any Enum

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;
    }
}
like image 230
Bob Horn Avatar asked May 21 '14 22:05

Bob Horn


People also ask

How do you find the value of an enum?

To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.

Can you extend enum C#?

The reason you can't extend Enums is because it would lead to problems with polymorphism.

Can you add methods to enums?

An enum class can include methods and fields just like regular classes. When we create an enum class, the compiler will create instances (objects) of each enum constants. Also, all enum constant is always public static final by default.


1 Answers

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.

like image 53
Jon Avatar answered Oct 19 '22 23:10

Jon