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 could declare your method like this:
Then you can call it
Extension method to get the values of any enum in C#
Based on solutions above with slightly different approach:
Usage
Test
.net c# enum extension
You can return an instance of the appropriate enum type (created using reflection), but its static type cannot be
List<EnumType>
. That would requireEnumType
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:
which you can invoke with
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.Since you are looking for the extension method, here it is:
EDIT
I will incorporate my comment in Bob's answer here:
So, I think we could all agree that there is no best solution for this, since it is not possible to do a where clause constraint on Enum type. Another solution would be to have a following method signature (as Bob suggested):
What we would do better with this solution is the constraint only on Enum values. However, in comparison to the generic solution, we lose the information about the enum type, on which we are invoking your extension method. So we need to cast it again. And I do not see much difference between this and the approach originally posted in by Bob in his question, where he returns
List<int>
and needs to cast it back to our enum.The most elegant solution can be achieved by using Code Contracts with static checking. However it requires usage of the code contracts and it would probably an overkill if they are to be used in this single case. This approach was addressed in the following thread: Using code contracts to make a generic to be of type enum
I'm wondering if I'm missing something because all of the answers use a generic method as part of the solution. Why not just do something like this?
The fiddle is here: https://dotnetfiddle.net/FRDuvD
This way this extension method will only be available to enums. Using the generics approach, the extension method seems to be available to all types:
It would be better not to have Values() available to a string at compile time.
How about this