4

I have the following generic function:

public SomeType SomeFunction<T>(T value)
{
}

I would now like to restrict this generic function to work only with Enums so I tried the following:

public SomeType SomeFunction<T>(T value) where T : System.Enum
{
}

But this resulted in:

error CS0702: Constraint cannot be special class 'System.Enum'

Is there a work around and out of curiosity does anyone know the reason why this type of constraint isn't allowed?

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
  • You should take a look at the accepted answer in the dupe mentioned by Ani. This is a restriction of the C# language, not the CLR (for example, it's possible to constrain to `enum` in F#). The Unconstrained Melody library provides a workaround to allow `enum` constraints in C# itself: http://code.google.com/p/unconstrained-melody/ – LukeH Nov 19 '10 at 10:47

2 Answers2

5

You can't. You can restrict it to value types, but that's all. Restricting it to enums can only be done using runtime checking:

public SomeType SomeFunction<T>(T value) where T : struct
{
    if (!typeof(T).IsEnum)
    {
        throw new NotSupportedException("Only enums are supported.");
    }
}
Steven
  • 166,672
  • 24
  • 332
  • 435
  • 1
    +1. It's also worth noting that System.Enum isn't an enum. – Moo-Juice Nov 19 '10 at 10:30
  • The problem is that I have another, non generic, function with the same name that's not being called now because all calls to `SomeFunction` get routed to the generic version, gah! – Andreas Brinck Nov 19 '10 at 10:32
  • You can actually make the constraint a little tighter too, not that it really helps much: `where T : struct, IComparable, IConvertible, IFormattable` – LukeH Nov 19 '10 at 10:32
  • @Moo-Juice: Is System.Enum not an enum, the same way System.ValueType isn't a value type? – Matt Ellen Nov 19 '10 at 10:39
  • @Matt correct. System.ValueType is merely a container for when a value-type is boxed so is therefore useless as a generic parameter. And System.Enum derives from it :) – Moo-Juice Nov 19 '10 at 10:41
1

Steven is correct, but you can narrow it a little before you throw an exception

public SomeType SomeFunction<T>(T value) where T : struct
Dean Chalk
  • 20,076
  • 6
  • 59
  • 90
  • 2
    That's less than what Steven said. -1 – Matt Ellen Nov 19 '10 at 10:32
  • 1
    The -1 is not deserved, because I edited my answer to add the `where T : struct` later on. This edit possibly crossed this post. – Steven Nov 19 '10 at 11:47
  • Ok, but (according to SO timekeeping) you answered 5 minutes after Steven. You both must have done ninja edits if you're saying that your answer had more info than Steven's at some point, because I can't see any edits to either answer. Sorry if this is the case. – Matt Ellen Nov 19 '10 at 11:54