I suggest you ...

Expand Generic Constraints for constructors

Currently when declaring a generic constraint on a Type parameter
ie.
public void DoSomething<T>() where T : new() { /* do something */ }

You can't specify that T has a constructor with specific parameters:
ie.
public void DoSomething<T>() where T : new(string, int) { /* do something */ }

3,388 votes
Vote
Sign in
Check!
(thinking…)
Reset
or sign in with
  • facebook
  • google
    Password icon
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    Michael Paterson shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →

    34 comments

    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      Signed in as (Sign out)
      Submitting...
      • Eamon Nerbonne commented  ·   ·  Flag as inappropriate

        It would be much more useful it the constraints could be a little more general and not just for constructors. Operators spring to mind as being even more useful, and perhaps other static methods too.

      • Tom Potts commented  ·   ·  Flag as inappropriate

        @giuseppe-lippolis I think you're confused; you can already do this with the current type system. Leaving your interface definition as it is, your class signature should be
        public class SelectableCollection<TItem, TValue> : ICollection<TItem> where TItem : ISelectableItem<TValue>

      • Brannon B. King commented  ·   ·  Flag as inappropriate

        I also would like a parent class on the numeric types that was usable. As an alternate, it might be nice to constrain types by operator availability.

        I also think we should fix the method resolution to use constraints as part of the method footprint. That way you could use generic type constraints on extension methods.

      • Giuseppe Lippolis commented  ·   ·  Flag as inappropriate

        another constraint interested to implement, it is a constraint that verifies if the generic type defined implements a specific generic Interface.
        example:

        public interface ISelectableItem <TValue>
        {
        bool IsSelected {get; sets;}
        TValue Value {get; sets;}
        }

        public class SelectableCollection <TItem>: ObeservableCollection <TItem>
        where TItem: ISelectableItem <?>
        {
        public void SelectAll()
        {
        foreach item in this
        item.IsSelected = true;
        }
        }

      • Marius Goppelt commented  ·   ·  Flag as inappropriate

        ... and please regard visibility. Currently, new constraint is always assumed as public. It suffices if the method which calls "Invoke" has sufficient access to the constructor. This is very useful for a factory pattern, where I don't want to expose the constructor.

        And don't forget VB.NET while you are at it! ;-)

      • CSharpJohn commented  ·   ·  Flag as inappropriate

        @michael >> where T : int or long or float or double <<

        The issue is the lack of good generic math, specifically the lack of parent types or interfaces for int, long, float... like INumber, IInteger, IFloat.

        This said, I agree re; generic constraints
        ValueType does not cut it.

      • David commented  ·   ·  Flag as inappropriate

        I like this. Here is yet another suggestion on the same line...
        as far as I'm aware, you can't do the following:

        public void DoSomething<T>() where T : Nullable
        OR
        public void DoSomething<T>() where T : NOT(Nullable)

        or somehow specify that T can (or cannot) be null. Recently I wanted to allow an "int?", or "long?" or "double?" (etc.) but not an "int", "long", or "double" but couldn't figure out how to do this. You CAN do this:

        public void DoSomething<T>() where T : class

        but that's not quite the same thing.

      • chha commented  ·   ·  Flag as inappropriate

        Yes, that's something I would also look forward to.

        Language: VB.NET

      • Ulrich Bu commented  ·   ·  Flag as inappropriate

        Yes. Another suggestion:

        public T Add(T a, T b) where T : int or long or float or double
        {
        return a + b;
        }

      2 Next →

      Feedback and Knowledge Base