Erix
Erix

Reputation: 7105

Pass a constrained type to a method

There a few similar questions here on SO, but none seem to quite answer my question..

I want to create a method which takes an Enum Type, and generates a List of ListItems for the UI. Something with a signature like this could work:

public static List<ListItem> ListItemListFromEnum(Type t)
{
    ...        
}

But I would prefer not to accept any type (t must be an Enum type) So I could do something like this:

public static List<ListItem> ListItemListFromEnum(Enum e)
{
    Type t = e.GetType();
}

and just pass an enum of the correct type to the method. That would work fine, but I'd really like to take a Type parameter (as in my first example) but force it to be an Enum type.

Is this possible? Is there a way to do it with generics? Thanks

Upvotes: 4

Views: 646

Answers (2)

vcsjones
vcsjones

Reputation: 141678

As of C# 7.3, this is now possible:

public static List<ListItem> ListItemsListFromEnum<T>() where T:System.Enum

And T will be constrained to an enum. Note you must use the type Enum, the keyword enum will not compile.

In prior versions of C#, this is not possible.

If you cannot use that version of C#, you can just accept the Type as you are and check the IsEnum property. If it is, throw an Exception.

public static List<ListItem> ListItemListFromEnum(Type t)
{
    if (!t.IsEnum)
    {
        throw new ArgumentException("Type must be an enumeration", "t");
    }     
}

Likewise you could do the same with a generic:

public static List<ListItem> ListItemListFromEnum<T>()
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("Type must be an enumeration", "t");
    }     
}

The only negative there is you will get a runtime exception rather than a compile-time one.

Upvotes: 6

James Michael Hare
James Michael Hare

Reputation: 38427

You can accept the Type and then throw if that type is not an enum type. That is probably the best way (until C# allows generic type placeholders to be constrained by Enum, if ever).

public static List<ListItem> ListItemListFromEnum(Type t)
{
        if (!t.IsEnum)
        {
            throw new ArgumentException("The type passed in must be an enum type.");                
        }

        // ...
}

This is what C# itself does with many of the Enum class's static methods (such as Enum.GetEnumNames()).

Upvotes: 1

Related Questions