Anyone know a good workaround for the lack of an enum generic constraint?












82















What I want to do is something like this: I have enums with combined flagged values.



public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}


So then I could do:



MyEnum tester = MyEnum.FlagA | MyEnum.FlagB

if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a


Unfortunately, C#'s generic where constraints have no enum restriction, only class and struct. C# doesn't see enums as structs (even though they are value types) so I can't add extension types like this.



Does anyone know a workaround?










share|improve this question




















  • 2





    Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

    – Jon Skeet
    Sep 11 '09 at 21:22











  • What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

    – Timwi
    Sep 25 '10 at 19:38











  • check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

    – dmihailescu
    Jul 1 '11 at 14:44








  • 1





    Vote for this uservoice idea, if you would like to see it built-in in .net one day.

    – Matthieu
    Apr 24 '14 at 14:02






  • 7





    C# 7.3 introduces enum constraints.

    – Marc Sigrist
    Apr 10 '18 at 12:02
















82















What I want to do is something like this: I have enums with combined flagged values.



public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}


So then I could do:



MyEnum tester = MyEnum.FlagA | MyEnum.FlagB

if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a


Unfortunately, C#'s generic where constraints have no enum restriction, only class and struct. C# doesn't see enums as structs (even though they are value types) so I can't add extension types like this.



Does anyone know a workaround?










share|improve this question




















  • 2





    Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

    – Jon Skeet
    Sep 11 '09 at 21:22











  • What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

    – Timwi
    Sep 25 '10 at 19:38











  • check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

    – dmihailescu
    Jul 1 '11 at 14:44








  • 1





    Vote for this uservoice idea, if you would like to see it built-in in .net one day.

    – Matthieu
    Apr 24 '14 at 14:02






  • 7





    C# 7.3 introduces enum constraints.

    – Marc Sigrist
    Apr 10 '18 at 12:02














82












82








82


23






What I want to do is something like this: I have enums with combined flagged values.



public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}


So then I could do:



MyEnum tester = MyEnum.FlagA | MyEnum.FlagB

if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a


Unfortunately, C#'s generic where constraints have no enum restriction, only class and struct. C# doesn't see enums as structs (even though they are value types) so I can't add extension types like this.



Does anyone know a workaround?










share|improve this question
















What I want to do is something like this: I have enums with combined flagged values.



public static class EnumExtension
{
public static bool IsSet<T>( this T input, T matchTo )
where T:enum //the constraint I want that doesn't exist in C#3
{
return (input & matchTo) != 0;
}
}


So then I could do:



MyEnum tester = MyEnum.FlagA | MyEnum.FlagB

if( tester.IsSet( MyEnum.FlagA ) )
//act on flag a


Unfortunately, C#'s generic where constraints have no enum restriction, only class and struct. C# doesn't see enums as structs (even though they are value types) so I can't add extension types like this.



Does anyone know a workaround?







c# .net enums flags






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 20 at 13:55









Ijas Ameenudeen

6,78732847




6,78732847










asked Aug 10 '08 at 17:14









KeithKeith

92.9k58233349




92.9k58233349








  • 2





    Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

    – Jon Skeet
    Sep 11 '09 at 21:22











  • What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

    – Timwi
    Sep 25 '10 at 19:38











  • check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

    – dmihailescu
    Jul 1 '11 at 14:44








  • 1





    Vote for this uservoice idea, if you would like to see it built-in in .net one day.

    – Matthieu
    Apr 24 '14 at 14:02






  • 7





    C# 7.3 introduces enum constraints.

    – Marc Sigrist
    Apr 10 '18 at 12:02














  • 2





    Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

    – Jon Skeet
    Sep 11 '09 at 21:22











  • What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

    – Timwi
    Sep 25 '10 at 19:38











  • check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

    – dmihailescu
    Jul 1 '11 at 14:44








  • 1





    Vote for this uservoice idea, if you would like to see it built-in in .net one day.

    – Matthieu
    Apr 24 '14 at 14:02






  • 7





    C# 7.3 introduces enum constraints.

    – Marc Sigrist
    Apr 10 '18 at 12:02








2




2





Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

– Jon Skeet
Sep 11 '09 at 21:22





Keith: download version 0.0.0.2 of UnconstrainedMelody - I've implemented HasAll and HasAny. Enjoy.

– Jon Skeet
Sep 11 '09 at 21:22













What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

– Timwi
Sep 25 '10 at 19:38





What do you mean by “C# doesn't see enums as structs”? You can use enum types as type parameters that are constrained to struct just fine.

– Timwi
Sep 25 '10 at 19:38













check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

– dmihailescu
Jul 1 '11 at 14:44







check this article here: codeproject.com/KB/cs/ExtendEnum.aspx 'IsValidEnumValue' or 'IsFlagsEnumDefined' methods are probably the answer to your question.

– dmihailescu
Jul 1 '11 at 14:44






1




1





Vote for this uservoice idea, if you would like to see it built-in in .net one day.

– Matthieu
Apr 24 '14 at 14:02





Vote for this uservoice idea, if you would like to see it built-in in .net one day.

– Matthieu
Apr 24 '14 at 14:02




7




7





C# 7.3 introduces enum constraints.

– Marc Sigrist
Apr 10 '18 at 12:02





C# 7.3 introduces enum constraints.

– Marc Sigrist
Apr 10 '18 at 12:02












12 Answers
12






active

oldest

votes


















47














EDIT: This is now live in version 0.0.0.2 of UnconstrainedMelody.



(As requested on my blog post about enum constraints. I've included the basic facts below for the sake of a standalone answer.)



The best solution is to wait for me to include it in UnconstrainedMelody1. This is a library which takes C# code with "fake" constraints such as



where T : struct, IEnumConstraint


and turns it into



where T : struct, System.Enum


via a postbuild step.



It shouldn't be too hard to write IsSet... although catering for both Int64-based and UInt64-based flags could be the tricky part. (I smell some helper methods coming on, basically allowing me to treat any flags enum as if it had a base type of UInt64.)



What would you want the behaviour to be if you called



tester.IsSet(MyFlags.A | MyFlags.C)


? Should it check that all the specified flags are set? That would be my expectation.



I'll try to do this on the way home tonight... I'm hoping to have a quick blitz on useful enum methods to get the library up to a usable standard quickly, then relax a bit.



EDIT: I'm not sure about IsSet as a name, by the way. Options:




  • Includes

  • Contains

  • HasFlag (or HasFlags)

  • IsSet (it's certainly an option)


Thoughts welcome. I'm sure it'll be a while before anything's set in stone anyway...





1 or submit it as a patch, of course...






share|improve this answer





















  • 1





    You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

    – Sam Harwell
    Sep 11 '09 at 9:34






  • 1





    Or actually simpler HasAny() and HasAll()

    – Keith
    Sep 11 '09 at 10:39






  • 1





    Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

    – Blixt
    Sep 11 '09 at 10:49






  • 1





    Yup, I like HasAny and HasAll too. Will go with that.

    – Jon Skeet
    Sep 11 '09 at 10:56






  • 1





    HasAny and HasAll seem awesome.

    – IDisposable
    Sep 15 '09 at 23:29



















16














Darren, that would work if the types were specific enumerations - for general enumerations to work you have to cast them to ints (or more likely uint) to do the boolean math:



public static bool IsSet( this Enum input, Enum matchTo )
{
return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
}





share|improve this answer



















  • 1





    And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

    – Kit
    Sep 10 '09 at 2:42











  • Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

    – ToolmakerSteve
    Mar 19 '14 at 6:56








  • 1





    Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

    – Groo
    Dec 18 '14 at 15:08





















11














As of C# 7.3, there is now a built-in way to add enum constraints:



public class UsingEnum<T> where T : System.Enum { }


source: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint






share|improve this answer



















  • 1





    I did not see your answer before posting mine. +1

    – Mik
    May 18 '18 at 13:07






  • 3





    Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

    – ForeverZer0
    Jul 15 '18 at 1:20











  • @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

    – Mik
    Aug 20 '18 at 20:28











  • @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

    – ForeverZer0
    Aug 20 '18 at 20:31





















9














Actually, it is possible, with an ugly trick.
However, it cannot be used for extension methods.



public abstract class Enums<Temp> where Temp : class {
public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
return (TEnum)Enum.Parse(typeof(TEnum), name);
}
}
public abstract class Enums : Enums<Enum> { }

Enums.IsSet<DateTimeKind>("Local")


If you want to, you can give Enums<Temp> a private constructor and a public nested abstract inherited class with Temp as Enum, to prevent inherited versions for non-enums.






share|improve this answer































    8














    You can achieve this using IL Weaving and ExtraConstraints



    Allows you to write this code



    public class Sample
    {
    public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
    {
    }
    public void MethodWithEnumConstraint<[EnumConstraint] T>()
    {
    }
    }


    What gets compiled



    public class Sample
    {
    public void MethodWithDelegateConstraint<T>() where T: Delegate
    {
    }

    public void MethodWithEnumConstraint<T>() where T: struct, Enum
    {
    }
    }





    share|improve this answer

































      4














      This doesn't answer the original question, but there is now a method in .NET 4 called Enum.HasFlag which does what you are trying to do in your example






      share|improve this answer
























      • Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

        – CptRobby
        Nov 20 '14 at 20:01











      • Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

        – Jeppe Stig Nielsen
        Apr 19 '15 at 8:57



















      3














      The way I do it is put a struct constraint, then check that T is an enum at runtime. This doesn't eliminate the problem completely, but it does reduce it somewhat






      share|improve this answer



















      • 7





        where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

        – Kit
        Sep 10 '09 at 2:39



















      2














      As of C# 7.3, you can use the Enum constraint on generic types:



      public static TEnum Parse<TEnum>(string value) where TEnum : Enum
      {
      return (TEnum) Enum.Parse(typeof(TEnum), value);
      }


      If you want to use a Nullable enum, you must leave the orginial struct constraint:



      public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
      {
      if( Enum.TryParse(value, out TEnum res) )
      return res;
      else
      return null;
      }





      share|improve this answer































        1














        Using your original code, inside the method you can also use reflection to test that T is an enum:



        public static class EnumExtension
        {
        public static bool IsSet<T>( this T input, T matchTo )
        {
        if (!typeof(T).IsEnum)
        {
        throw new ArgumentException("Must be an enum", "input");
        }
        return (input & matchTo) != 0;
        }
        }





        share|improve this answer





















        • 2





          Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

          – Keith
          Sep 11 '09 at 11:13



















        1














        Here's some code that I just did up that seems to work like you want without having to do anything too crazy. It's not restricted to only enums set as Flags, but there could always be a check put in if need be.



        public static class EnumExtensions
        {
        public static bool ContainsFlag(this Enum source, Enum flag)
        {
        var sourceValue = ToUInt64(source);
        var flagValue = ToUInt64(flag);

        return (sourceValue & flagValue) == flagValue;
        }

        public static bool ContainsAnyFlag(this Enum source, params Enum flags)
        {
        var sourceValue = ToUInt64(source);

        foreach (var flag in flags)
        {
        var flagValue = ToUInt64(flag);

        if ((sourceValue & flagValue) == flagValue)
        {
        return true;
        }
        }

        return false;
        }

        // found in the Enum class as an internal method
        private static ulong ToUInt64(object value)
        {
        switch (Convert.GetTypeCode(value))
        {
        case TypeCode.SByte:
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);

        case TypeCode.Byte:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
        return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
        }

        throw new InvalidOperationException("Unknown enum type.");
        }
        }





        share|improve this answer































          0














          if someone needs generic IsSet (created out of box on fly could be improved on), and or string to Enum onfly conversion (which uses EnumConstraint presented below):



            public class TestClass
          { }

          public struct TestStruct
          { }

          public enum TestEnum
          {
          e1,
          e2,
          e3
          }

          public static class TestEnumConstraintExtenssion
          {

          public static bool IsSet<TEnum>(this TEnum _this, TEnum flag)
          where TEnum : struct
          {
          return (((uint)Convert.ChangeType(_this, typeof(uint))) & ((uint)Convert.ChangeType(flag, typeof(uint)))) == ((uint)Convert.ChangeType(flag, typeof(uint)));
          }

          //public static TestClass ToTestClass(this string _this)
          //{
          // // #generates compile error (so no missuse)
          // return EnumConstraint.TryParse<TestClass>(_this);
          //}

          //public static TestStruct ToTestStruct(this string _this)
          //{
          // // #generates compile error (so no missuse)
          // return EnumConstraint.TryParse<TestStruct>(_this);
          //}

          public static TestEnum ToTestEnum(this string _this)
          {
          // #enum type works just fine (coding constraint to Enum type)
          return EnumConstraint.TryParse<TestEnum>(_this);
          }

          public static void TestAll()
          {
          TestEnum t1 = "e3".ToTestEnum();
          TestEnum t2 = "e2".ToTestEnum();
          TestEnum t3 = "non existing".ToTestEnum(); // default(TestEnum) for non existing

          bool b1 = t3.IsSet(TestEnum.e1); // you can ommit type
          bool b2 = t3.IsSet<TestEnum>(TestEnum.e2); // you can specify explicite type

          TestStruct t;
          // #generates compile error (so no missuse)
          //bool b3 = t.IsSet<TestEnum>(TestEnum.e1);

          }

          }


          If someone still needs example hot to create Enum coding constraint:



          using System;

          /// <summary>
          /// would be same as EnumConstraint_T&lt;Enum>Parse&lt;EnumType>("Normal"),
          /// but writen like this it abuses constrain inheritence on System.Enum.
          /// </summary>
          public class EnumConstraint : EnumConstraint_T<Enum>
          {

          }

          /// <summary>
          /// provides ability to constrain TEnum to System.Enum abusing constrain inheritence
          /// </summary>
          /// <typeparam name="TClass">should be System.Enum</typeparam>
          public abstract class EnumConstraint_T<TClass>
          where TClass : class
          {

          public static TEnum Parse<TEnum>(string value)
          where TEnum : TClass
          {
          return (TEnum)Enum.Parse(typeof(TEnum), value);
          }

          public static bool TryParse<TEnum>(string value, out TEnum evalue)
          where TEnum : struct, TClass // struct is required to ignore non nullable type error
          {
          evalue = default(TEnum);
          return Enum.TryParse<TEnum>(value, out evalue);
          }

          public static TEnum TryParse<TEnum>(string value, TEnum defaultValue = default(TEnum))
          where TEnum : struct, TClass // struct is required to ignore non nullable type error
          {
          Enum.TryParse<TEnum>(value, out defaultValue);
          return defaultValue;
          }

          public static TEnum Parse<TEnum>(string value, TEnum defaultValue = default(TEnum))
          where TEnum : struct, TClass // struct is required to ignore non nullable type error
          {
          TEnum result;
          if (Enum.TryParse<TEnum>(value, out result))
          return result;
          return defaultValue;
          }

          public static TEnum Parse<TEnum>(ushort value)
          {
          return (TEnum)(object)value;
          }

          public static sbyte to_i1<TEnum>(TEnum value)
          {
          return (sbyte)(object)Convert.ChangeType(value, typeof(sbyte));
          }

          public static byte to_u1<TEnum>(TEnum value)
          {
          return (byte)(object)Convert.ChangeType(value, typeof(byte));
          }

          public static short to_i2<TEnum>(TEnum value)
          {
          return (short)(object)Convert.ChangeType(value, typeof(short));
          }

          public static ushort to_u2<TEnum>(TEnum value)
          {
          return (ushort)(object)Convert.ChangeType(value, typeof(ushort));
          }

          public static int to_i4<TEnum>(TEnum value)
          {
          return (int)(object)Convert.ChangeType(value, typeof(int));
          }

          public static uint to_u4<TEnum>(TEnum value)
          {
          return (uint)(object)Convert.ChangeType(value, typeof(uint));
          }

          }


          hope this helps someone.






          share|improve this answer































            0














            I just wanted to add Enum as a generic constraint.



            While this is just for a tiny helper method using ExtraConstraints is a bit too much overhead for me.



            I decided to just just create a struct constraint and add a runtime check for IsEnum. For converting a variable from T to Enum I cast it to object first.



                public static Converter<T, string> CreateConverter<T>() where T : struct
            {
            if (!typeof(T).IsEnum) throw new ArgumentException("Given Type is not an Enum");
            return new Converter<T, string>(x => ((Enum)(object)x).GetEnumDescription());
            }





            share|improve this answer

























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7244%2fanyone-know-a-good-workaround-for-the-lack-of-an-enum-generic-constraint%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              12 Answers
              12






              active

              oldest

              votes








              12 Answers
              12






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              47














              EDIT: This is now live in version 0.0.0.2 of UnconstrainedMelody.



              (As requested on my blog post about enum constraints. I've included the basic facts below for the sake of a standalone answer.)



              The best solution is to wait for me to include it in UnconstrainedMelody1. This is a library which takes C# code with "fake" constraints such as



              where T : struct, IEnumConstraint


              and turns it into



              where T : struct, System.Enum


              via a postbuild step.



              It shouldn't be too hard to write IsSet... although catering for both Int64-based and UInt64-based flags could be the tricky part. (I smell some helper methods coming on, basically allowing me to treat any flags enum as if it had a base type of UInt64.)



              What would you want the behaviour to be if you called



              tester.IsSet(MyFlags.A | MyFlags.C)


              ? Should it check that all the specified flags are set? That would be my expectation.



              I'll try to do this on the way home tonight... I'm hoping to have a quick blitz on useful enum methods to get the library up to a usable standard quickly, then relax a bit.



              EDIT: I'm not sure about IsSet as a name, by the way. Options:




              • Includes

              • Contains

              • HasFlag (or HasFlags)

              • IsSet (it's certainly an option)


              Thoughts welcome. I'm sure it'll be a while before anything's set in stone anyway...





              1 or submit it as a patch, of course...






              share|improve this answer





















              • 1





                You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

                – Sam Harwell
                Sep 11 '09 at 9:34






              • 1





                Or actually simpler HasAny() and HasAll()

                – Keith
                Sep 11 '09 at 10:39






              • 1





                Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

                – Blixt
                Sep 11 '09 at 10:49






              • 1





                Yup, I like HasAny and HasAll too. Will go with that.

                – Jon Skeet
                Sep 11 '09 at 10:56






              • 1





                HasAny and HasAll seem awesome.

                – IDisposable
                Sep 15 '09 at 23:29
















              47














              EDIT: This is now live in version 0.0.0.2 of UnconstrainedMelody.



              (As requested on my blog post about enum constraints. I've included the basic facts below for the sake of a standalone answer.)



              The best solution is to wait for me to include it in UnconstrainedMelody1. This is a library which takes C# code with "fake" constraints such as



              where T : struct, IEnumConstraint


              and turns it into



              where T : struct, System.Enum


              via a postbuild step.



              It shouldn't be too hard to write IsSet... although catering for both Int64-based and UInt64-based flags could be the tricky part. (I smell some helper methods coming on, basically allowing me to treat any flags enum as if it had a base type of UInt64.)



              What would you want the behaviour to be if you called



              tester.IsSet(MyFlags.A | MyFlags.C)


              ? Should it check that all the specified flags are set? That would be my expectation.



              I'll try to do this on the way home tonight... I'm hoping to have a quick blitz on useful enum methods to get the library up to a usable standard quickly, then relax a bit.



              EDIT: I'm not sure about IsSet as a name, by the way. Options:




              • Includes

              • Contains

              • HasFlag (or HasFlags)

              • IsSet (it's certainly an option)


              Thoughts welcome. I'm sure it'll be a while before anything's set in stone anyway...





              1 or submit it as a patch, of course...






              share|improve this answer





















              • 1





                You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

                – Sam Harwell
                Sep 11 '09 at 9:34






              • 1





                Or actually simpler HasAny() and HasAll()

                – Keith
                Sep 11 '09 at 10:39






              • 1





                Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

                – Blixt
                Sep 11 '09 at 10:49






              • 1





                Yup, I like HasAny and HasAll too. Will go with that.

                – Jon Skeet
                Sep 11 '09 at 10:56






              • 1





                HasAny and HasAll seem awesome.

                – IDisposable
                Sep 15 '09 at 23:29














              47












              47








              47







              EDIT: This is now live in version 0.0.0.2 of UnconstrainedMelody.



              (As requested on my blog post about enum constraints. I've included the basic facts below for the sake of a standalone answer.)



              The best solution is to wait for me to include it in UnconstrainedMelody1. This is a library which takes C# code with "fake" constraints such as



              where T : struct, IEnumConstraint


              and turns it into



              where T : struct, System.Enum


              via a postbuild step.



              It shouldn't be too hard to write IsSet... although catering for both Int64-based and UInt64-based flags could be the tricky part. (I smell some helper methods coming on, basically allowing me to treat any flags enum as if it had a base type of UInt64.)



              What would you want the behaviour to be if you called



              tester.IsSet(MyFlags.A | MyFlags.C)


              ? Should it check that all the specified flags are set? That would be my expectation.



              I'll try to do this on the way home tonight... I'm hoping to have a quick blitz on useful enum methods to get the library up to a usable standard quickly, then relax a bit.



              EDIT: I'm not sure about IsSet as a name, by the way. Options:




              • Includes

              • Contains

              • HasFlag (or HasFlags)

              • IsSet (it's certainly an option)


              Thoughts welcome. I'm sure it'll be a while before anything's set in stone anyway...





              1 or submit it as a patch, of course...






              share|improve this answer















              EDIT: This is now live in version 0.0.0.2 of UnconstrainedMelody.



              (As requested on my blog post about enum constraints. I've included the basic facts below for the sake of a standalone answer.)



              The best solution is to wait for me to include it in UnconstrainedMelody1. This is a library which takes C# code with "fake" constraints such as



              where T : struct, IEnumConstraint


              and turns it into



              where T : struct, System.Enum


              via a postbuild step.



              It shouldn't be too hard to write IsSet... although catering for both Int64-based and UInt64-based flags could be the tricky part. (I smell some helper methods coming on, basically allowing me to treat any flags enum as if it had a base type of UInt64.)



              What would you want the behaviour to be if you called



              tester.IsSet(MyFlags.A | MyFlags.C)


              ? Should it check that all the specified flags are set? That would be my expectation.



              I'll try to do this on the way home tonight... I'm hoping to have a quick blitz on useful enum methods to get the library up to a usable standard quickly, then relax a bit.



              EDIT: I'm not sure about IsSet as a name, by the way. Options:




              • Includes

              • Contains

              • HasFlag (or HasFlags)

              • IsSet (it's certainly an option)


              Thoughts welcome. I'm sure it'll be a while before anything's set in stone anyway...





              1 or submit it as a patch, of course...







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Mar 29 '16 at 5:40

























              answered Sep 11 '09 at 9:12









              Jon SkeetJon Skeet

              1086k68779268428




              1086k68779268428








              • 1





                You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

                – Sam Harwell
                Sep 11 '09 at 9:34






              • 1





                Or actually simpler HasAny() and HasAll()

                – Keith
                Sep 11 '09 at 10:39






              • 1





                Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

                – Blixt
                Sep 11 '09 at 10:49






              • 1





                Yup, I like HasAny and HasAll too. Will go with that.

                – Jon Skeet
                Sep 11 '09 at 10:56






              • 1





                HasAny and HasAll seem awesome.

                – IDisposable
                Sep 15 '09 at 23:29














              • 1





                You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

                – Sam Harwell
                Sep 11 '09 at 9:34






              • 1





                Or actually simpler HasAny() and HasAll()

                – Keith
                Sep 11 '09 at 10:39






              • 1





                Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

                – Blixt
                Sep 11 '09 at 10:49






              • 1





                Yup, I like HasAny and HasAll too. Will go with that.

                – Jon Skeet
                Sep 11 '09 at 10:56






              • 1





                HasAny and HasAll seem awesome.

                – IDisposable
                Sep 15 '09 at 23:29








              1




              1





              You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

              – Sam Harwell
              Sep 11 '09 at 9:34





              You had to go and mention PostSharp LOL :o postsharp.org/blog/generic-constraints-for-enums-and-delegates

              – Sam Harwell
              Sep 11 '09 at 9:34




              1




              1





              Or actually simpler HasAny() and HasAll()

              – Keith
              Sep 11 '09 at 10:39





              Or actually simpler HasAny() and HasAll()

              – Keith
              Sep 11 '09 at 10:39




              1




              1





              Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

              – Blixt
              Sep 11 '09 at 10:49





              Yes, I agree that's even better. colors.HasAny(Colors.Red | Colors.Blue) looks like very readable code. =)

              – Blixt
              Sep 11 '09 at 10:49




              1




              1





              Yup, I like HasAny and HasAll too. Will go with that.

              – Jon Skeet
              Sep 11 '09 at 10:56





              Yup, I like HasAny and HasAll too. Will go with that.

              – Jon Skeet
              Sep 11 '09 at 10:56




              1




              1





              HasAny and HasAll seem awesome.

              – IDisposable
              Sep 15 '09 at 23:29





              HasAny and HasAll seem awesome.

              – IDisposable
              Sep 15 '09 at 23:29













              16














              Darren, that would work if the types were specific enumerations - for general enumerations to work you have to cast them to ints (or more likely uint) to do the boolean math:



              public static bool IsSet( this Enum input, Enum matchTo )
              {
              return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
              }





              share|improve this answer



















              • 1





                And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

                – Kit
                Sep 10 '09 at 2:42











              • Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

                – ToolmakerSteve
                Mar 19 '14 at 6:56








              • 1





                Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

                – Groo
                Dec 18 '14 at 15:08


















              16














              Darren, that would work if the types were specific enumerations - for general enumerations to work you have to cast them to ints (or more likely uint) to do the boolean math:



              public static bool IsSet( this Enum input, Enum matchTo )
              {
              return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
              }





              share|improve this answer



















              • 1





                And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

                – Kit
                Sep 10 '09 at 2:42











              • Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

                – ToolmakerSteve
                Mar 19 '14 at 6:56








              • 1





                Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

                – Groo
                Dec 18 '14 at 15:08
















              16












              16








              16







              Darren, that would work if the types were specific enumerations - for general enumerations to work you have to cast them to ints (or more likely uint) to do the boolean math:



              public static bool IsSet( this Enum input, Enum matchTo )
              {
              return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
              }





              share|improve this answer













              Darren, that would work if the types were specific enumerations - for general enumerations to work you have to cast them to ints (or more likely uint) to do the boolean math:



              public static bool IsSet( this Enum input, Enum matchTo )
              {
              return ( Convert.ToUInt32( input ) & Convert.ToUInt32( matchTo ) ) != 0;
              }






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Aug 10 '08 at 22:53









              RonnieRonnie

              6,23652532




              6,23652532








              • 1





                And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

                – Kit
                Sep 10 '09 at 2:42











              • Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

                – ToolmakerSteve
                Mar 19 '14 at 6:56








              • 1





                Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

                – Groo
                Dec 18 '14 at 15:08
















              • 1





                And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

                – Kit
                Sep 10 '09 at 2:42











              • Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

                – ToolmakerSteve
                Mar 19 '14 at 6:56








              • 1





                Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

                – Groo
                Dec 18 '14 at 15:08










              1




              1





              And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

              – Kit
              Sep 10 '09 at 2:42





              And if you have a ridiculous number of flags, you can call GetTypeCode() on the arguments and Convert.ToUint64()

              – Kit
              Sep 10 '09 at 2:42













              Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

              – ToolmakerSteve
              Mar 19 '14 at 6:56







              Awesome, the combination of 'Enum` and Convert.ToUInt32 I didn't find anywhere else. AFAIK, Its the only decent Pre-Net-4 solution that also works in VB. BTW, if matchTo might have multiple flag bits, then replace != 0 with == Convert.ToUInt32(matchTo).

              – ToolmakerSteve
              Mar 19 '14 at 6:56






              1




              1





              Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

              – Groo
              Dec 18 '14 at 15:08







              Note that Convert.ToUInt32 used with an enum will use the Convert.ToUInt32(object) overload, meaning that CLR will first box these values before passing then to the ToUInt32 method. In most cases this won't matter, but it's good to know that you'll keep the GC rather busy if you're using something like this to parse millions of enums per second.

              – Groo
              Dec 18 '14 at 15:08













              11














              As of C# 7.3, there is now a built-in way to add enum constraints:



              public class UsingEnum<T> where T : System.Enum { }


              source: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint






              share|improve this answer



















              • 1





                I did not see your answer before posting mine. +1

                – Mik
                May 18 '18 at 13:07






              • 3





                Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

                – ForeverZer0
                Jul 15 '18 at 1:20











              • @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

                – Mik
                Aug 20 '18 at 20:28











              • @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

                – ForeverZer0
                Aug 20 '18 at 20:31


















              11














              As of C# 7.3, there is now a built-in way to add enum constraints:



              public class UsingEnum<T> where T : System.Enum { }


              source: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint






              share|improve this answer



















              • 1





                I did not see your answer before posting mine. +1

                – Mik
                May 18 '18 at 13:07






              • 3





                Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

                – ForeverZer0
                Jul 15 '18 at 1:20











              • @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

                – Mik
                Aug 20 '18 at 20:28











              • @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

                – ForeverZer0
                Aug 20 '18 at 20:31
















              11












              11








              11







              As of C# 7.3, there is now a built-in way to add enum constraints:



              public class UsingEnum<T> where T : System.Enum { }


              source: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint






              share|improve this answer













              As of C# 7.3, there is now a built-in way to add enum constraints:



              public class UsingEnum<T> where T : System.Enum { }


              source: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/where-generic-type-constraint







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered May 11 '18 at 9:33









              Ivan FerićIvan Ferić

              4,137113045




              4,137113045








              • 1





                I did not see your answer before posting mine. +1

                – Mik
                May 18 '18 at 13:07






              • 3





                Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

                – ForeverZer0
                Jul 15 '18 at 1:20











              • @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

                – Mik
                Aug 20 '18 at 20:28











              • @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

                – ForeverZer0
                Aug 20 '18 at 20:31
















              • 1





                I did not see your answer before posting mine. +1

                – Mik
                May 18 '18 at 13:07






              • 3





                Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

                – ForeverZer0
                Jul 15 '18 at 1:20











              • @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

                – Mik
                Aug 20 '18 at 20:28











              • @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

                – ForeverZer0
                Aug 20 '18 at 20:31










              1




              1





              I did not see your answer before posting mine. +1

              – Mik
              May 18 '18 at 13:07





              I did not see your answer before posting mine. +1

              – Mik
              May 18 '18 at 13:07




              3




              3





              Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

              – ForeverZer0
              Jul 15 '18 at 1:20





              Too bad the "accepted" and most widely viewed answer is no longer up-to-date to reflect changes in the language. Someone who does not know and just skimming the the most popular answer will not be getting the most relevant and up-to-date information.

              – ForeverZer0
              Jul 15 '18 at 1:20













              @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

              – Mik
              Aug 20 '18 at 20:28





              @ForeverZer0 I think most people using SO know that when the answer is rather old, it might exist a better one below it.

              – Mik
              Aug 20 '18 at 20:28













              @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

              – ForeverZer0
              Aug 20 '18 at 20:31







              @Mik Obviously, was just thinking out loud. Thank you for pointing that out. Was just stating because currently it is 4 answers down.

              – ForeverZer0
              Aug 20 '18 at 20:31













              9














              Actually, it is possible, with an ugly trick.
              However, it cannot be used for extension methods.



              public abstract class Enums<Temp> where Temp : class {
              public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
              return (TEnum)Enum.Parse(typeof(TEnum), name);
              }
              }
              public abstract class Enums : Enums<Enum> { }

              Enums.IsSet<DateTimeKind>("Local")


              If you want to, you can give Enums<Temp> a private constructor and a public nested abstract inherited class with Temp as Enum, to prevent inherited versions for non-enums.






              share|improve this answer




























                9














                Actually, it is possible, with an ugly trick.
                However, it cannot be used for extension methods.



                public abstract class Enums<Temp> where Temp : class {
                public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
                return (TEnum)Enum.Parse(typeof(TEnum), name);
                }
                }
                public abstract class Enums : Enums<Enum> { }

                Enums.IsSet<DateTimeKind>("Local")


                If you want to, you can give Enums<Temp> a private constructor and a public nested abstract inherited class with Temp as Enum, to prevent inherited versions for non-enums.






                share|improve this answer


























                  9












                  9








                  9







                  Actually, it is possible, with an ugly trick.
                  However, it cannot be used for extension methods.



                  public abstract class Enums<Temp> where Temp : class {
                  public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
                  return (TEnum)Enum.Parse(typeof(TEnum), name);
                  }
                  }
                  public abstract class Enums : Enums<Enum> { }

                  Enums.IsSet<DateTimeKind>("Local")


                  If you want to, you can give Enums<Temp> a private constructor and a public nested abstract inherited class with Temp as Enum, to prevent inherited versions for non-enums.






                  share|improve this answer













                  Actually, it is possible, with an ugly trick.
                  However, it cannot be used for extension methods.



                  public abstract class Enums<Temp> where Temp : class {
                  public static TEnum Parse<TEnum>(string name) where TEnum : struct, Temp {
                  return (TEnum)Enum.Parse(typeof(TEnum), name);
                  }
                  }
                  public abstract class Enums : Enums<Enum> { }

                  Enums.IsSet<DateTimeKind>("Local")


                  If you want to, you can give Enums<Temp> a private constructor and a public nested abstract inherited class with Temp as Enum, to prevent inherited versions for non-enums.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Sep 13 '09 at 2:41









                  SLaksSLaks

                  684k13916391758




                  684k13916391758























                      8














                      You can achieve this using IL Weaving and ExtraConstraints



                      Allows you to write this code



                      public class Sample
                      {
                      public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
                      {
                      }
                      public void MethodWithEnumConstraint<[EnumConstraint] T>()
                      {
                      }
                      }


                      What gets compiled



                      public class Sample
                      {
                      public void MethodWithDelegateConstraint<T>() where T: Delegate
                      {
                      }

                      public void MethodWithEnumConstraint<T>() where T: struct, Enum
                      {
                      }
                      }





                      share|improve this answer






























                        8














                        You can achieve this using IL Weaving and ExtraConstraints



                        Allows you to write this code



                        public class Sample
                        {
                        public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
                        {
                        }
                        public void MethodWithEnumConstraint<[EnumConstraint] T>()
                        {
                        }
                        }


                        What gets compiled



                        public class Sample
                        {
                        public void MethodWithDelegateConstraint<T>() where T: Delegate
                        {
                        }

                        public void MethodWithEnumConstraint<T>() where T: struct, Enum
                        {
                        }
                        }





                        share|improve this answer




























                          8












                          8








                          8







                          You can achieve this using IL Weaving and ExtraConstraints



                          Allows you to write this code



                          public class Sample
                          {
                          public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
                          {
                          }
                          public void MethodWithEnumConstraint<[EnumConstraint] T>()
                          {
                          }
                          }


                          What gets compiled



                          public class Sample
                          {
                          public void MethodWithDelegateConstraint<T>() where T: Delegate
                          {
                          }

                          public void MethodWithEnumConstraint<T>() where T: struct, Enum
                          {
                          }
                          }





                          share|improve this answer















                          You can achieve this using IL Weaving and ExtraConstraints



                          Allows you to write this code



                          public class Sample
                          {
                          public void MethodWithDelegateConstraint<[DelegateConstraint] T> ()
                          {
                          }
                          public void MethodWithEnumConstraint<[EnumConstraint] T>()
                          {
                          }
                          }


                          What gets compiled



                          public class Sample
                          {
                          public void MethodWithDelegateConstraint<T>() where T: Delegate
                          {
                          }

                          public void MethodWithEnumConstraint<T>() where T: struct, Enum
                          {
                          }
                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Mar 19 '14 at 10:31

























                          answered Jul 20 '12 at 7:11









                          SimonSimon

                          21.4k15106162




                          21.4k15106162























                              4














                              This doesn't answer the original question, but there is now a method in .NET 4 called Enum.HasFlag which does what you are trying to do in your example






                              share|improve this answer
























                              • Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                                – CptRobby
                                Nov 20 '14 at 20:01











                              • Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                                – Jeppe Stig Nielsen
                                Apr 19 '15 at 8:57
















                              4














                              This doesn't answer the original question, but there is now a method in .NET 4 called Enum.HasFlag which does what you are trying to do in your example






                              share|improve this answer
























                              • Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                                – CptRobby
                                Nov 20 '14 at 20:01











                              • Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                                – Jeppe Stig Nielsen
                                Apr 19 '15 at 8:57














                              4












                              4








                              4







                              This doesn't answer the original question, but there is now a method in .NET 4 called Enum.HasFlag which does what you are trying to do in your example






                              share|improve this answer













                              This doesn't answer the original question, but there is now a method in .NET 4 called Enum.HasFlag which does what you are trying to do in your example







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 20 '09 at 11:08









                              Phil DevaneyPhil Devaney

                              15k53529




                              15k53529













                              • Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                                – CptRobby
                                Nov 20 '14 at 20:01











                              • Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                                – Jeppe Stig Nielsen
                                Apr 19 '15 at 8:57



















                              • Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                                – CptRobby
                                Nov 20 '14 at 20:01











                              • Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                                – Jeppe Stig Nielsen
                                Apr 19 '15 at 8:57

















                              Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                              – CptRobby
                              Nov 20 '14 at 20:01





                              Upvoted because at this point, most everyone should be using .NET 4 (or higher) and so they should be using this method instead of trying to hack it together.

                              – CptRobby
                              Nov 20 '14 at 20:01













                              Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                              – Jeppe Stig Nielsen
                              Apr 19 '15 at 8:57





                              Upvoted. However their solution uses boxing of the argument flag. .NET 4.0 is five years old now.

                              – Jeppe Stig Nielsen
                              Apr 19 '15 at 8:57











                              3














                              The way I do it is put a struct constraint, then check that T is an enum at runtime. This doesn't eliminate the problem completely, but it does reduce it somewhat






                              share|improve this answer



















                              • 7





                                where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                                – Kit
                                Sep 10 '09 at 2:39
















                              3














                              The way I do it is put a struct constraint, then check that T is an enum at runtime. This doesn't eliminate the problem completely, but it does reduce it somewhat






                              share|improve this answer



















                              • 7





                                where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                                – Kit
                                Sep 10 '09 at 2:39














                              3












                              3








                              3







                              The way I do it is put a struct constraint, then check that T is an enum at runtime. This doesn't eliminate the problem completely, but it does reduce it somewhat






                              share|improve this answer













                              The way I do it is put a struct constraint, then check that T is an enum at runtime. This doesn't eliminate the problem completely, but it does reduce it somewhat







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jul 27 '09 at 14:02









                              thecoopthecoop

                              35.5k11105162




                              35.5k11105162








                              • 7





                                where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                                – Kit
                                Sep 10 '09 at 2:39














                              • 7





                                where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                                – Kit
                                Sep 10 '09 at 2:39








                              7




                              7





                              where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                              – Kit
                              Sep 10 '09 at 2:39





                              where T : struct, IComparable, IFormattable, IConvertible -- this is the closest you can get to enum :)

                              – Kit
                              Sep 10 '09 at 2:39











                              2














                              As of C# 7.3, you can use the Enum constraint on generic types:



                              public static TEnum Parse<TEnum>(string value) where TEnum : Enum
                              {
                              return (TEnum) Enum.Parse(typeof(TEnum), value);
                              }


                              If you want to use a Nullable enum, you must leave the orginial struct constraint:



                              public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
                              {
                              if( Enum.TryParse(value, out TEnum res) )
                              return res;
                              else
                              return null;
                              }





                              share|improve this answer




























                                2














                                As of C# 7.3, you can use the Enum constraint on generic types:



                                public static TEnum Parse<TEnum>(string value) where TEnum : Enum
                                {
                                return (TEnum) Enum.Parse(typeof(TEnum), value);
                                }


                                If you want to use a Nullable enum, you must leave the orginial struct constraint:



                                public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
                                {
                                if( Enum.TryParse(value, out TEnum res) )
                                return res;
                                else
                                return null;
                                }





                                share|improve this answer


























                                  2












                                  2








                                  2







                                  As of C# 7.3, you can use the Enum constraint on generic types:



                                  public static TEnum Parse<TEnum>(string value) where TEnum : Enum
                                  {
                                  return (TEnum) Enum.Parse(typeof(TEnum), value);
                                  }


                                  If you want to use a Nullable enum, you must leave the orginial struct constraint:



                                  public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
                                  {
                                  if( Enum.TryParse(value, out TEnum res) )
                                  return res;
                                  else
                                  return null;
                                  }





                                  share|improve this answer













                                  As of C# 7.3, you can use the Enum constraint on generic types:



                                  public static TEnum Parse<TEnum>(string value) where TEnum : Enum
                                  {
                                  return (TEnum) Enum.Parse(typeof(TEnum), value);
                                  }


                                  If you want to use a Nullable enum, you must leave the orginial struct constraint:



                                  public static TEnum? TryParse<TEnum>(string value) where TEnum : struct, Enum
                                  {
                                  if( Enum.TryParse(value, out TEnum res) )
                                  return res;
                                  else
                                  return null;
                                  }






                                  share|improve this answer












                                  share|improve this answer



                                  share|improve this answer










                                  answered May 18 '18 at 13:04









                                  MikMik

                                  341212




                                  341212























                                      1














                                      Using your original code, inside the method you can also use reflection to test that T is an enum:



                                      public static class EnumExtension
                                      {
                                      public static bool IsSet<T>( this T input, T matchTo )
                                      {
                                      if (!typeof(T).IsEnum)
                                      {
                                      throw new ArgumentException("Must be an enum", "input");
                                      }
                                      return (input & matchTo) != 0;
                                      }
                                      }





                                      share|improve this answer





















                                      • 2





                                        Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                        – Keith
                                        Sep 11 '09 at 11:13
















                                      1














                                      Using your original code, inside the method you can also use reflection to test that T is an enum:



                                      public static class EnumExtension
                                      {
                                      public static bool IsSet<T>( this T input, T matchTo )
                                      {
                                      if (!typeof(T).IsEnum)
                                      {
                                      throw new ArgumentException("Must be an enum", "input");
                                      }
                                      return (input & matchTo) != 0;
                                      }
                                      }





                                      share|improve this answer





















                                      • 2





                                        Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                        – Keith
                                        Sep 11 '09 at 11:13














                                      1












                                      1








                                      1







                                      Using your original code, inside the method you can also use reflection to test that T is an enum:



                                      public static class EnumExtension
                                      {
                                      public static bool IsSet<T>( this T input, T matchTo )
                                      {
                                      if (!typeof(T).IsEnum)
                                      {
                                      throw new ArgumentException("Must be an enum", "input");
                                      }
                                      return (input & matchTo) != 0;
                                      }
                                      }





                                      share|improve this answer















                                      Using your original code, inside the method you can also use reflection to test that T is an enum:



                                      public static class EnumExtension
                                      {
                                      public static bool IsSet<T>( this T input, T matchTo )
                                      {
                                      if (!typeof(T).IsEnum)
                                      {
                                      throw new ArgumentException("Must be an enum", "input");
                                      }
                                      return (input & matchTo) != 0;
                                      }
                                      }






                                      share|improve this answer














                                      share|improve this answer



                                      share|improve this answer








                                      edited Aug 28 '08 at 15:19









                                      Keith

                                      92.9k58233349




                                      92.9k58233349










                                      answered Aug 17 '08 at 4:51









                                      Scott DormanScott Dorman

                                      34.9k1068105




                                      34.9k1068105








                                      • 2





                                        Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                        – Keith
                                        Sep 11 '09 at 11:13














                                      • 2





                                        Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                        – Keith
                                        Sep 11 '09 at 11:13








                                      2




                                      2





                                      Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                      – Keith
                                      Sep 11 '09 at 11:13





                                      Thanks, but that turns a compile time issue (the where constraint) into a runtime one (your exception). Also you'd still need to convert the inputs to ints before you could do anything with them.

                                      – Keith
                                      Sep 11 '09 at 11:13











                                      1














                                      Here's some code that I just did up that seems to work like you want without having to do anything too crazy. It's not restricted to only enums set as Flags, but there could always be a check put in if need be.



                                      public static class EnumExtensions
                                      {
                                      public static bool ContainsFlag(this Enum source, Enum flag)
                                      {
                                      var sourceValue = ToUInt64(source);
                                      var flagValue = ToUInt64(flag);

                                      return (sourceValue & flagValue) == flagValue;
                                      }

                                      public static bool ContainsAnyFlag(this Enum source, params Enum flags)
                                      {
                                      var sourceValue = ToUInt64(source);

                                      foreach (var flag in flags)
                                      {
                                      var flagValue = ToUInt64(flag);

                                      if ((sourceValue & flagValue) == flagValue)
                                      {
                                      return true;
                                      }
                                      }

                                      return false;
                                      }

                                      // found in the Enum class as an internal method
                                      private static ulong ToUInt64(object value)
                                      {
                                      switch (Convert.GetTypeCode(value))
                                      {
                                      case TypeCode.SByte:
                                      case TypeCode.Int16:
                                      case TypeCode.Int32:
                                      case TypeCode.Int64:
                                      return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);

                                      case TypeCode.Byte:
                                      case TypeCode.UInt16:
                                      case TypeCode.UInt32:
                                      case TypeCode.UInt64:
                                      return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
                                      }

                                      throw new InvalidOperationException("Unknown enum type.");
                                      }
                                      }





                                      share|improve this answer




























                                        1














                                        Here's some code that I just did up that seems to work like you want without having to do anything too crazy. It's not restricted to only enums set as Flags, but there could always be a check put in if need be.



                                        public static class EnumExtensions
                                        {
                                        public static bool ContainsFlag(this Enum source, Enum flag)
                                        {
                                        var sourceValue = ToUInt64(source);
                                        var flagValue = ToUInt64(flag);

                                        return (sourceValue & flagValue) == flagValue;
                                        }

                                        public static bool ContainsAnyFlag(this Enum source, params Enum flags)
                                        {
                                        var sourceValue = ToUInt64(source);

                                        foreach (var flag in flags)
                                        {
                                        var flagValue = ToUInt64(flag);

                                        if ((sourceValue & flagValue) == flagValue)
                                        {
                                        return true;
                                        }
                                        }

                                        return false;
                                        }

                                        // found in the Enum class as an internal method
                                        private static ulong ToUInt64(object value)
                                        {
                                        switch (Convert.GetTypeCode(value))
                                        {
                                        case TypeCode.SByte:
                                        case TypeCode.Int16:
                                        case TypeCode.Int32:
                                        case TypeCode.Int64:
                                        return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);

                                        case TypeCode.Byte:
                                        case TypeCode.UInt16:
                                        case TypeCode.UInt32:
                                        case TypeCode.UInt64:
                                        return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
                                        }

                                        throw new InvalidOperationException("Unknown enum type.");
                                        }
                                        }





                                        share|improve this answer


























                                          1












                                          1








                                          1







                                          Here's some code that I just did up that seems to work like you want without having to do anything too crazy. It's not restricted to only enums set as Flags, but there could always be a check put in if need be.



                                          public static class EnumExtensions
                                          {
                                          public static bool ContainsFlag(this Enum source, Enum flag)
                                          {
                                          var sourceValue = ToUInt64(source);
                                          var flagValue = ToUInt64(flag);

                                          return (sourceValue & flagValue) == flagValue;
                                          }

                                          public static bool ContainsAnyFlag(this Enum source, params Enum flags)
                                          {
                                          var sourceValue = ToUInt64(source);

                                          foreach (var flag in flags)
                                          {
                                          var flagValue = ToUInt64(flag);

                                          if ((sourceValue & flagValue) == flagValue)
                                          {
                                          return true;
                                          }
                                          }

                                          return false;
                                          }

                                          // found in the Enum class as an internal method
                                          private static ulong ToUInt64(object value)
                                          {
                                          switch (Convert.GetTypeCode(value))
                                          {
                                          case TypeCode.SByte:
                                          case TypeCode.Int16:
                                          case TypeCode.Int32:
                                          case TypeCode.Int64:
                                          return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);

                                          case TypeCode.Byte:
                                          case TypeCode.UInt16:
                                          case TypeCode.UInt32:
                                          case TypeCode.UInt64:
                                          return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
                                          }

                                          throw new InvalidOperationException("Unknown enum type.");
                                          }
                                          }





                                          share|improve this answer













                                          Here's some code that I just did up that seems to work like you want without having to do anything too crazy. It's not restricted to only enums set as Flags, but there could always be a check put in if need be.



                                          public static class EnumExtensions
                                          {
                                          public static bool ContainsFlag(this Enum source, Enum flag)
                                          {
                                          var sourceValue = ToUInt64(source);
                                          var flagValue = ToUInt64(flag);

                                          return (sourceValue & flagValue) == flagValue;
                                          }

                                          public static bool ContainsAnyFlag(this Enum source, params Enum flags)
                                          {
                                          var sourceValue = ToUInt64(source);

                                          foreach (var flag in flags)
                                          {
                                          var flagValue = ToUInt64(flag);

                                          if ((sourceValue & flagValue) == flagValue)
                                          {
                                          return true;
                                          }
                                          }

                                          return false;
                                          }

                                          // found in the Enum class as an internal method
                                          private static ulong ToUInt64(object value)
                                          {
                                          switch (Convert.GetTypeCode(value))
                                          {
                                          case TypeCode.SByte:
                                          case TypeCode.Int16:
                                          case TypeCode.Int32:
                                          case TypeCode.Int64:
                                          return (ulong)Convert.ToInt64(value, CultureInfo.InvariantCulture);

                                          case TypeCode.Byte:
                                          case TypeCode.UInt16:
                                          case TypeCode.UInt32:
                                          case TypeCode.UInt64:
                                          return Convert.ToUInt64(value, CultureInfo.InvariantCulture);
                                          }

                                          throw new InvalidOperationException("Unknown enum type.");
                                          }
                                          }






                                          share|improve this answer












                                          share|improve this answer



                                          share|improve this answer










                                          answered Sep 13 '09 at 3:57









                                          Brian SurowiecBrian Surowiec

                                          9,99063563




                                          9,99063563























                                              0














                                              if someone needs generic IsSet (created out of box on fly could be improved on), and or string to Enum onfly conversion (which uses EnumConstraint presented below):



                                                public class TestClass
                                              { }

                                              public struct TestStruct
                                              { }

                                              public enum TestEnum
                                              {
                                              e1,
                                              e2,
                                              e3
                                              }

                                              public static class TestEnumConstraintExtenssion
                                              {

                                              public static bool IsSet<TEnum>(this TEnum _this, TEnum flag)
                                              where TEnum : struct
                                              {
                                              return (((uint)Convert.ChangeType(_this, typeof(uint))) & ((uint)Convert.ChangeType(flag, typeof(uint)))) == ((uint)Convert.ChangeType(flag, typeof(uint)));
                                              }

                                              //public static TestClass ToTestClass(this string _this)
                                              //{
                                              // // #generates compile error (so no missuse)
                                              // return EnumConstraint.TryParse<TestClass>(_this);
                                              //}

                                              //public static TestStruct ToTestStruct(this string _this)
                                              //{
                                              // // #generates compile error (so no missuse)
                                              // return EnumConstraint.TryParse<TestStruct>(_this);
                                              //}

                                              public static TestEnum ToTestEnum(this string _this)
                                              {
                                              // #enum type works just fine (coding constraint to Enum type)
                                              return EnumConstraint.TryParse<TestEnum>(_this);
                                              }

                                              public static void TestAll()
                                              {
                                              TestEnum t1 = "e3".ToTestEnum();
                                              TestEnum t2 = "e2".ToTestEnum();
                                              TestEnum t3 = "non existing".ToTestEnum(); // default(TestEnum) for non existing

                                              bool b1 = t3.IsSet(TestEnum.e1); // you can ommit type
                                              bool b2 = t3.IsSet<TestEnum>(TestEnum.e2); // you can specify explicite type

                                              TestStruct t;
                                              // #generates compile error (so no missuse)
                                              //bool b3 = t.IsSet<TestEnum>(TestEnum.e1);

                                              }

                                              }


                                              If someone still needs example hot to create Enum coding constraint:



                                              using System;

                                              /// <summary>
                                              /// would be same as EnumConstraint_T&lt;Enum>Parse&lt;EnumType>("Normal"),
                                              /// but writen like this it abuses constrain inheritence on System.Enum.
                                              /// </summary>
                                              public class EnumConstraint : EnumConstraint_T<Enum>
                                              {

                                              }

                                              /// <summary>
                                              /// provides ability to constrain TEnum to System.Enum abusing constrain inheritence
                                              /// </summary>
                                              /// <typeparam name="TClass">should be System.Enum</typeparam>
                                              public abstract class EnumConstraint_T<TClass>
                                              where TClass : class
                                              {

                                              public static TEnum Parse<TEnum>(string value)
                                              where TEnum : TClass
                                              {
                                              return (TEnum)Enum.Parse(typeof(TEnum), value);
                                              }

                                              public static bool TryParse<TEnum>(string value, out TEnum evalue)
                                              where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                              {
                                              evalue = default(TEnum);
                                              return Enum.TryParse<TEnum>(value, out evalue);
                                              }

                                              public static TEnum TryParse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                              where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                              {
                                              Enum.TryParse<TEnum>(value, out defaultValue);
                                              return defaultValue;
                                              }

                                              public static TEnum Parse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                              where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                              {
                                              TEnum result;
                                              if (Enum.TryParse<TEnum>(value, out result))
                                              return result;
                                              return defaultValue;
                                              }

                                              public static TEnum Parse<TEnum>(ushort value)
                                              {
                                              return (TEnum)(object)value;
                                              }

                                              public static sbyte to_i1<TEnum>(TEnum value)
                                              {
                                              return (sbyte)(object)Convert.ChangeType(value, typeof(sbyte));
                                              }

                                              public static byte to_u1<TEnum>(TEnum value)
                                              {
                                              return (byte)(object)Convert.ChangeType(value, typeof(byte));
                                              }

                                              public static short to_i2<TEnum>(TEnum value)
                                              {
                                              return (short)(object)Convert.ChangeType(value, typeof(short));
                                              }

                                              public static ushort to_u2<TEnum>(TEnum value)
                                              {
                                              return (ushort)(object)Convert.ChangeType(value, typeof(ushort));
                                              }

                                              public static int to_i4<TEnum>(TEnum value)
                                              {
                                              return (int)(object)Convert.ChangeType(value, typeof(int));
                                              }

                                              public static uint to_u4<TEnum>(TEnum value)
                                              {
                                              return (uint)(object)Convert.ChangeType(value, typeof(uint));
                                              }

                                              }


                                              hope this helps someone.






                                              share|improve this answer




























                                                0














                                                if someone needs generic IsSet (created out of box on fly could be improved on), and or string to Enum onfly conversion (which uses EnumConstraint presented below):



                                                  public class TestClass
                                                { }

                                                public struct TestStruct
                                                { }

                                                public enum TestEnum
                                                {
                                                e1,
                                                e2,
                                                e3
                                                }

                                                public static class TestEnumConstraintExtenssion
                                                {

                                                public static bool IsSet<TEnum>(this TEnum _this, TEnum flag)
                                                where TEnum : struct
                                                {
                                                return (((uint)Convert.ChangeType(_this, typeof(uint))) & ((uint)Convert.ChangeType(flag, typeof(uint)))) == ((uint)Convert.ChangeType(flag, typeof(uint)));
                                                }

                                                //public static TestClass ToTestClass(this string _this)
                                                //{
                                                // // #generates compile error (so no missuse)
                                                // return EnumConstraint.TryParse<TestClass>(_this);
                                                //}

                                                //public static TestStruct ToTestStruct(this string _this)
                                                //{
                                                // // #generates compile error (so no missuse)
                                                // return EnumConstraint.TryParse<TestStruct>(_this);
                                                //}

                                                public static TestEnum ToTestEnum(this string _this)
                                                {
                                                // #enum type works just fine (coding constraint to Enum type)
                                                return EnumConstraint.TryParse<TestEnum>(_this);
                                                }

                                                public static void TestAll()
                                                {
                                                TestEnum t1 = "e3".ToTestEnum();
                                                TestEnum t2 = "e2".ToTestEnum();
                                                TestEnum t3 = "non existing".ToTestEnum(); // default(TestEnum) for non existing

                                                bool b1 = t3.IsSet(TestEnum.e1); // you can ommit type
                                                bool b2 = t3.IsSet<TestEnum>(TestEnum.e2); // you can specify explicite type

                                                TestStruct t;
                                                // #generates compile error (so no missuse)
                                                //bool b3 = t.IsSet<TestEnum>(TestEnum.e1);

                                                }

                                                }


                                                If someone still needs example hot to create Enum coding constraint:



                                                using System;

                                                /// <summary>
                                                /// would be same as EnumConstraint_T&lt;Enum>Parse&lt;EnumType>("Normal"),
                                                /// but writen like this it abuses constrain inheritence on System.Enum.
                                                /// </summary>
                                                public class EnumConstraint : EnumConstraint_T<Enum>
                                                {

                                                }

                                                /// <summary>
                                                /// provides ability to constrain TEnum to System.Enum abusing constrain inheritence
                                                /// </summary>
                                                /// <typeparam name="TClass">should be System.Enum</typeparam>
                                                public abstract class EnumConstraint_T<TClass>
                                                where TClass : class
                                                {

                                                public static TEnum Parse<TEnum>(string value)
                                                where TEnum : TClass
                                                {
                                                return (TEnum)Enum.Parse(typeof(TEnum), value);
                                                }

                                                public static bool TryParse<TEnum>(string value, out TEnum evalue)
                                                where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                {
                                                evalue = default(TEnum);
                                                return Enum.TryParse<TEnum>(value, out evalue);
                                                }

                                                public static TEnum TryParse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                {
                                                Enum.TryParse<TEnum>(value, out defaultValue);
                                                return defaultValue;
                                                }

                                                public static TEnum Parse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                {
                                                TEnum result;
                                                if (Enum.TryParse<TEnum>(value, out result))
                                                return result;
                                                return defaultValue;
                                                }

                                                public static TEnum Parse<TEnum>(ushort value)
                                                {
                                                return (TEnum)(object)value;
                                                }

                                                public static sbyte to_i1<TEnum>(TEnum value)
                                                {
                                                return (sbyte)(object)Convert.ChangeType(value, typeof(sbyte));
                                                }

                                                public static byte to_u1<TEnum>(TEnum value)
                                                {
                                                return (byte)(object)Convert.ChangeType(value, typeof(byte));
                                                }

                                                public static short to_i2<TEnum>(TEnum value)
                                                {
                                                return (short)(object)Convert.ChangeType(value, typeof(short));
                                                }

                                                public static ushort to_u2<TEnum>(TEnum value)
                                                {
                                                return (ushort)(object)Convert.ChangeType(value, typeof(ushort));
                                                }

                                                public static int to_i4<TEnum>(TEnum value)
                                                {
                                                return (int)(object)Convert.ChangeType(value, typeof(int));
                                                }

                                                public static uint to_u4<TEnum>(TEnum value)
                                                {
                                                return (uint)(object)Convert.ChangeType(value, typeof(uint));
                                                }

                                                }


                                                hope this helps someone.






                                                share|improve this answer


























                                                  0












                                                  0








                                                  0







                                                  if someone needs generic IsSet (created out of box on fly could be improved on), and or string to Enum onfly conversion (which uses EnumConstraint presented below):



                                                    public class TestClass
                                                  { }

                                                  public struct TestStruct
                                                  { }

                                                  public enum TestEnum
                                                  {
                                                  e1,
                                                  e2,
                                                  e3
                                                  }

                                                  public static class TestEnumConstraintExtenssion
                                                  {

                                                  public static bool IsSet<TEnum>(this TEnum _this, TEnum flag)
                                                  where TEnum : struct
                                                  {
                                                  return (((uint)Convert.ChangeType(_this, typeof(uint))) & ((uint)Convert.ChangeType(flag, typeof(uint)))) == ((uint)Convert.ChangeType(flag, typeof(uint)));
                                                  }

                                                  //public static TestClass ToTestClass(this string _this)
                                                  //{
                                                  // // #generates compile error (so no missuse)
                                                  // return EnumConstraint.TryParse<TestClass>(_this);
                                                  //}

                                                  //public static TestStruct ToTestStruct(this string _this)
                                                  //{
                                                  // // #generates compile error (so no missuse)
                                                  // return EnumConstraint.TryParse<TestStruct>(_this);
                                                  //}

                                                  public static TestEnum ToTestEnum(this string _this)
                                                  {
                                                  // #enum type works just fine (coding constraint to Enum type)
                                                  return EnumConstraint.TryParse<TestEnum>(_this);
                                                  }

                                                  public static void TestAll()
                                                  {
                                                  TestEnum t1 = "e3".ToTestEnum();
                                                  TestEnum t2 = "e2".ToTestEnum();
                                                  TestEnum t3 = "non existing".ToTestEnum(); // default(TestEnum) for non existing

                                                  bool b1 = t3.IsSet(TestEnum.e1); // you can ommit type
                                                  bool b2 = t3.IsSet<TestEnum>(TestEnum.e2); // you can specify explicite type

                                                  TestStruct t;
                                                  // #generates compile error (so no missuse)
                                                  //bool b3 = t.IsSet<TestEnum>(TestEnum.e1);

                                                  }

                                                  }


                                                  If someone still needs example hot to create Enum coding constraint:



                                                  using System;

                                                  /// <summary>
                                                  /// would be same as EnumConstraint_T&lt;Enum>Parse&lt;EnumType>("Normal"),
                                                  /// but writen like this it abuses constrain inheritence on System.Enum.
                                                  /// </summary>
                                                  public class EnumConstraint : EnumConstraint_T<Enum>
                                                  {

                                                  }

                                                  /// <summary>
                                                  /// provides ability to constrain TEnum to System.Enum abusing constrain inheritence
                                                  /// </summary>
                                                  /// <typeparam name="TClass">should be System.Enum</typeparam>
                                                  public abstract class EnumConstraint_T<TClass>
                                                  where TClass : class
                                                  {

                                                  public static TEnum Parse<TEnum>(string value)
                                                  where TEnum : TClass
                                                  {
                                                  return (TEnum)Enum.Parse(typeof(TEnum), value);
                                                  }

                                                  public static bool TryParse<TEnum>(string value, out TEnum evalue)
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  evalue = default(TEnum);
                                                  return Enum.TryParse<TEnum>(value, out evalue);
                                                  }

                                                  public static TEnum TryParse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  Enum.TryParse<TEnum>(value, out defaultValue);
                                                  return defaultValue;
                                                  }

                                                  public static TEnum Parse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  TEnum result;
                                                  if (Enum.TryParse<TEnum>(value, out result))
                                                  return result;
                                                  return defaultValue;
                                                  }

                                                  public static TEnum Parse<TEnum>(ushort value)
                                                  {
                                                  return (TEnum)(object)value;
                                                  }

                                                  public static sbyte to_i1<TEnum>(TEnum value)
                                                  {
                                                  return (sbyte)(object)Convert.ChangeType(value, typeof(sbyte));
                                                  }

                                                  public static byte to_u1<TEnum>(TEnum value)
                                                  {
                                                  return (byte)(object)Convert.ChangeType(value, typeof(byte));
                                                  }

                                                  public static short to_i2<TEnum>(TEnum value)
                                                  {
                                                  return (short)(object)Convert.ChangeType(value, typeof(short));
                                                  }

                                                  public static ushort to_u2<TEnum>(TEnum value)
                                                  {
                                                  return (ushort)(object)Convert.ChangeType(value, typeof(ushort));
                                                  }

                                                  public static int to_i4<TEnum>(TEnum value)
                                                  {
                                                  return (int)(object)Convert.ChangeType(value, typeof(int));
                                                  }

                                                  public static uint to_u4<TEnum>(TEnum value)
                                                  {
                                                  return (uint)(object)Convert.ChangeType(value, typeof(uint));
                                                  }

                                                  }


                                                  hope this helps someone.






                                                  share|improve this answer













                                                  if someone needs generic IsSet (created out of box on fly could be improved on), and or string to Enum onfly conversion (which uses EnumConstraint presented below):



                                                    public class TestClass
                                                  { }

                                                  public struct TestStruct
                                                  { }

                                                  public enum TestEnum
                                                  {
                                                  e1,
                                                  e2,
                                                  e3
                                                  }

                                                  public static class TestEnumConstraintExtenssion
                                                  {

                                                  public static bool IsSet<TEnum>(this TEnum _this, TEnum flag)
                                                  where TEnum : struct
                                                  {
                                                  return (((uint)Convert.ChangeType(_this, typeof(uint))) & ((uint)Convert.ChangeType(flag, typeof(uint)))) == ((uint)Convert.ChangeType(flag, typeof(uint)));
                                                  }

                                                  //public static TestClass ToTestClass(this string _this)
                                                  //{
                                                  // // #generates compile error (so no missuse)
                                                  // return EnumConstraint.TryParse<TestClass>(_this);
                                                  //}

                                                  //public static TestStruct ToTestStruct(this string _this)
                                                  //{
                                                  // // #generates compile error (so no missuse)
                                                  // return EnumConstraint.TryParse<TestStruct>(_this);
                                                  //}

                                                  public static TestEnum ToTestEnum(this string _this)
                                                  {
                                                  // #enum type works just fine (coding constraint to Enum type)
                                                  return EnumConstraint.TryParse<TestEnum>(_this);
                                                  }

                                                  public static void TestAll()
                                                  {
                                                  TestEnum t1 = "e3".ToTestEnum();
                                                  TestEnum t2 = "e2".ToTestEnum();
                                                  TestEnum t3 = "non existing".ToTestEnum(); // default(TestEnum) for non existing

                                                  bool b1 = t3.IsSet(TestEnum.e1); // you can ommit type
                                                  bool b2 = t3.IsSet<TestEnum>(TestEnum.e2); // you can specify explicite type

                                                  TestStruct t;
                                                  // #generates compile error (so no missuse)
                                                  //bool b3 = t.IsSet<TestEnum>(TestEnum.e1);

                                                  }

                                                  }


                                                  If someone still needs example hot to create Enum coding constraint:



                                                  using System;

                                                  /// <summary>
                                                  /// would be same as EnumConstraint_T&lt;Enum>Parse&lt;EnumType>("Normal"),
                                                  /// but writen like this it abuses constrain inheritence on System.Enum.
                                                  /// </summary>
                                                  public class EnumConstraint : EnumConstraint_T<Enum>
                                                  {

                                                  }

                                                  /// <summary>
                                                  /// provides ability to constrain TEnum to System.Enum abusing constrain inheritence
                                                  /// </summary>
                                                  /// <typeparam name="TClass">should be System.Enum</typeparam>
                                                  public abstract class EnumConstraint_T<TClass>
                                                  where TClass : class
                                                  {

                                                  public static TEnum Parse<TEnum>(string value)
                                                  where TEnum : TClass
                                                  {
                                                  return (TEnum)Enum.Parse(typeof(TEnum), value);
                                                  }

                                                  public static bool TryParse<TEnum>(string value, out TEnum evalue)
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  evalue = default(TEnum);
                                                  return Enum.TryParse<TEnum>(value, out evalue);
                                                  }

                                                  public static TEnum TryParse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  Enum.TryParse<TEnum>(value, out defaultValue);
                                                  return defaultValue;
                                                  }

                                                  public static TEnum Parse<TEnum>(string value, TEnum defaultValue = default(TEnum))
                                                  where TEnum : struct, TClass // struct is required to ignore non nullable type error
                                                  {
                                                  TEnum result;
                                                  if (Enum.TryParse<TEnum>(value, out result))
                                                  return result;
                                                  return defaultValue;
                                                  }

                                                  public static TEnum Parse<TEnum>(ushort value)
                                                  {
                                                  return (TEnum)(object)value;
                                                  }

                                                  public static sbyte to_i1<TEnum>(TEnum value)
                                                  {
                                                  return (sbyte)(object)Convert.ChangeType(value, typeof(sbyte));
                                                  }

                                                  public static byte to_u1<TEnum>(TEnum value)
                                                  {
                                                  return (byte)(object)Convert.ChangeType(value, typeof(byte));
                                                  }

                                                  public static short to_i2<TEnum>(TEnum value)
                                                  {
                                                  return (short)(object)Convert.ChangeType(value, typeof(short));
                                                  }

                                                  public static ushort to_u2<TEnum>(TEnum value)
                                                  {
                                                  return (ushort)(object)Convert.ChangeType(value, typeof(ushort));
                                                  }

                                                  public static int to_i4<TEnum>(TEnum value)
                                                  {
                                                  return (int)(object)Convert.ChangeType(value, typeof(int));
                                                  }

                                                  public static uint to_u4<TEnum>(TEnum value)
                                                  {
                                                  return (uint)(object)Convert.ChangeType(value, typeof(uint));
                                                  }

                                                  }


                                                  hope this helps someone.







                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered Dec 22 '16 at 8:42









                                                  SoLaRSoLaR

                                                  394213




                                                  394213























                                                      0














                                                      I just wanted to add Enum as a generic constraint.



                                                      While this is just for a tiny helper method using ExtraConstraints is a bit too much overhead for me.



                                                      I decided to just just create a struct constraint and add a runtime check for IsEnum. For converting a variable from T to Enum I cast it to object first.



                                                          public static Converter<T, string> CreateConverter<T>() where T : struct
                                                      {
                                                      if (!typeof(T).IsEnum) throw new ArgumentException("Given Type is not an Enum");
                                                      return new Converter<T, string>(x => ((Enum)(object)x).GetEnumDescription());
                                                      }





                                                      share|improve this answer






























                                                        0














                                                        I just wanted to add Enum as a generic constraint.



                                                        While this is just for a tiny helper method using ExtraConstraints is a bit too much overhead for me.



                                                        I decided to just just create a struct constraint and add a runtime check for IsEnum. For converting a variable from T to Enum I cast it to object first.



                                                            public static Converter<T, string> CreateConverter<T>() where T : struct
                                                        {
                                                        if (!typeof(T).IsEnum) throw new ArgumentException("Given Type is not an Enum");
                                                        return new Converter<T, string>(x => ((Enum)(object)x).GetEnumDescription());
                                                        }





                                                        share|improve this answer




























                                                          0












                                                          0








                                                          0







                                                          I just wanted to add Enum as a generic constraint.



                                                          While this is just for a tiny helper method using ExtraConstraints is a bit too much overhead for me.



                                                          I decided to just just create a struct constraint and add a runtime check for IsEnum. For converting a variable from T to Enum I cast it to object first.



                                                              public static Converter<T, string> CreateConverter<T>() where T : struct
                                                          {
                                                          if (!typeof(T).IsEnum) throw new ArgumentException("Given Type is not an Enum");
                                                          return new Converter<T, string>(x => ((Enum)(object)x).GetEnumDescription());
                                                          }





                                                          share|improve this answer















                                                          I just wanted to add Enum as a generic constraint.



                                                          While this is just for a tiny helper method using ExtraConstraints is a bit too much overhead for me.



                                                          I decided to just just create a struct constraint and add a runtime check for IsEnum. For converting a variable from T to Enum I cast it to object first.



                                                              public static Converter<T, string> CreateConverter<T>() where T : struct
                                                          {
                                                          if (!typeof(T).IsEnum) throw new ArgumentException("Given Type is not an Enum");
                                                          return new Converter<T, string>(x => ((Enum)(object)x).GetEnumDescription());
                                                          }






                                                          share|improve this answer














                                                          share|improve this answer



                                                          share|improve this answer








                                                          edited Jul 24 '17 at 9:46









                                                          BatteryBackupUnit

                                                          11k12748




                                                          11k12748










                                                          answered Mar 18 '16 at 7:49









                                                          Jürgen SteinblockJürgen Steinblock

                                                          19k1783149




                                                          19k1783149






























                                                              draft saved

                                                              draft discarded




















































                                                              Thanks for contributing an answer to Stack Overflow!


                                                              • Please be sure to answer the question. Provide details and share your research!

                                                              But avoid



                                                              • Asking for help, clarification, or responding to other answers.

                                                              • Making statements based on opinion; back them up with references or personal experience.


                                                              To learn more, see our tips on writing great answers.




                                                              draft saved


                                                              draft discarded














                                                              StackExchange.ready(
                                                              function () {
                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7244%2fanyone-know-a-good-workaround-for-the-lack-of-an-enum-generic-constraint%23new-answer', 'question_page');
                                                              }
                                                              );

                                                              Post as a guest















                                                              Required, but never shown





















































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown

































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown







                                                              Popular posts from this blog

                                                              Callistus III

                                                              Ostreoida

                                                              Plistias Cous