I suggest you ...

Add in support for Enum and Delegate constraints

Currently C# disallows constraints for
System.Enum,
System.ValueType,
System.Delegate,
System.Array,
System.Object

However, the CLR has support for classes constrained to All 5 types.
It could be very useful to have this constrain.
To constraint a method to enum we can just use:
where T:struct,Enum
Allowing us to specify only to be called on enum instances and not those boxed as Enum.

Delegate is less strict unfortunately, as there is no way to specify that a T must be an inheritor of a class. A simple solution would be to add an interface to Delegate like `IDelegate` so that we can easily specify only invokable types.

Array is not really necessary as we can make the method have this signature:
MyMethod<T>(T[] array)...

Object is a useless constraint as everything that can be used as a generic argument parameter has to be assignable to system.object.

ValueType isn't necessary as you can use the struct constraint.

231 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    I agree to the terms of service
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Michael Burbea shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    5 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      Submitting...
      • Keith Burgoyne commented  ·   ·  Flag as inappropriate

        Supporting "where T : enum" for enums rather than "where T : struct" has been missing since forever. It would eliminate performance hits by removing the need for performing "typeof(T).GetTypeInfo().IsEnum" and then throwing an exception at runtime when the compiler should have just refused to accept the code at compile-time.

      • Anonymous commented  ·   ·  Flag as inappropriate

        +1

        Let's give some examples where this would be particular useful:

        /// <summary>Typ safe Enum.Parse</summary>
        public static E Parse<E>(string value)
        where E : struct,IComparable,IConvertible,IFormattable
        // where E : Enum required but invalid constraint
        { return (E)Enum.Parse(typeof(E), value);
        }

        /// <summary>Get all enum values</summary>
        public static E[] GetValues<E>()
        where E : struct,IComparable,IConvertible,IFormattable
        // where E : Enum required but invalid constraint
        { return (E[])Enum.GetValues(typeof(E));
        }

        public static T CreateOpenInstanceDelegate<T>(this MethodInfo mi) where T : class
        // where T : MulticastDelegate
        { ... }

        /// <summary>Create Proxy to call constructor by delegate</summary>
        public static T CreateDelegate<T>(this ConstructorInfo ci) where T : class
        // where T : MulticastDelegate
        { ... }

      • Alex commented  ·   ·  Flag as inappropriate

        This is allowed in cil. Jon skeet wrote a library which contains dummy types and a program that replaces the dummies with actual constraints. If someone wanted it badly enough to make that, just make it default.

      • Joshua A. Schaeffer commented  ·   ·  Flag as inappropriate

        This is a no-brainer, I don't know why it doesn't get top votes considering how simple it is. Yes you can pass in a delegate as a generic parameter but it has to have a "class" constraint. And you can pass in an enum but it has to have a "struct" constraint. Inside the generic method though, there is no strong-typing against the delegate or the enum. There's no explainable reason for this.

      Feedback and Knowledge Base