Question

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!

Was it helpful?

Solution

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

OTHER TIPS

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.

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.

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
            }
        }
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top