1

This is an elaboration on this question: c# Enum Function Parameters

I created a little sample application to introduce my question:

UPDATE: This is a known difficulty on the C# programming language. I added the used workaround in the code for people that find this in a search engine.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace FlexibleEnums
{
    class Program
    {
        public enum Color
        {
            Blue,
            Red,
            Green
        };

        static void Main(string[] args)
        {
            CheckEnum<Color>();
            Console.ReadKey();
        }

        private static void CheckEnum<T>()
        {
            foreach (T item in Enum.GetValues(typeof(T)))
            {
                Console.WriteLine(item);

                // And here is the question:
                // I would like to uncheck this line, but that does not compile!
                //DoSomethingWithAnEnumValue(item);

                // Solution:
                // Not so nice, but it works.
                // (In the real program I also check for null off cource!)
                DoSomethingWithAnEnumValue(item as Enum);


            }

        }

        private static void DoSomethingWithAnEnumValue(Enum e)
        {
            Console.WriteLine(e);
        }

    }
}

I think that I should be doing something like:

private static void CheckEnum<T>() where T : Enum

But that's also giving me compile errors.

Thanks for the help!

Community
  • 1
  • 1
Sunib
  • 304
  • 2
  • 14
  • 1
    Minor quibble, but there's a difference between an enumeration (enum) and an enumerator (IEnumerator provided by an IEnumerable). For consistency, you may want to use the term Enum (which is well understood) or possibly enumeration (though this can also mean enumerating with an enumerator.) – Dan Bryant Nov 10 '11 at 14:57
  • agreed, as i say in my answer below, i think a more accurate way to phrase the question is 'how to place generic constraints on an enumeration value' – Jason Nov 10 '11 at 14:59
  • Did you try Google for "generic parameter restrict enum"? Lots of results on SO alone. – sq33G Nov 10 '11 at 14:59

4 Answers4

1

Since C#7.3, it has been possible to create an enum constraint: Enum constraints

public sealed class MyClass<T> : MyBaseClass, IMyInterface<T> where T : Enum
{
        public MyClass(Args args)
            : base(args)
        {
        }
}

I needed the consumer to pass in one of several enums, where the enum had to exist in a particular namespace. I threw a run-time exception if a different enum was used:

public sealed class MyClass<T> : MyBaseClass, IMyInterface<T> where T : Enum
{
        public MyClass(Args args)
            : base(args)
        {
            var t = typeof(T);
            if (t.Namespace.IsNotContaining("My.Namespace.Of.Interest"))
            {
#pragma warning disable CA1303 // Do not pass literals as localized parameters
                throw new InvalidEnumArgumentException("The enum provided was not of the expected type.");
#pragma warning restore CA1303 // Do not pass literals as localized parameters
            }
        }
}

DrGriff
  • 4,394
  • 9
  • 43
  • 92
1

I think the question can be restated as, 'how to place generic constraints on an enumeration value'.

Jon Skeet has blogged about it here: http://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for-enums-and-delegates.aspx

The question has been asked previously on SO

Community
  • 1
  • 1
Jason
  • 15,915
  • 3
  • 48
  • 72
0

It is not possible (I could not find a way when I had the same problem) to restrict a generic condition to Enum.

UPDATED

Closest you can get is to a ValueType struct:

where T : ValueType

where T : struct

NOTE: Apologies, yes it was struct thanks to n8wrl.

Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • Hmmm. That's giving me the same error as with the Enum: Constraint cannot be special class 'System.ValueType' – Sunib Nov 10 '11 at 14:56
0

You also need to make sure that DoSomethingWithAnEnumeraterValue(item) is typed to match your T:

private static void DoSomethingWithAnEnumeratorValue<T>(T item) where T : ...
{
}

where T is restricted the same way CheckEnumerator is.

n8wrl
  • 19,439
  • 4
  • 63
  • 103