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

1,003 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 PatersonMichael Paterson shared this idea  ·   ·  Flag idea as inappropriate…  ·  Admin →
    AnonymousAnonymous shared a merged idea: Add new constraint on type parameters in C#: where new(parameters)  ·   · 

    15 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...
      • Mark SeemannMark Seemann commented  ·   ·  Flag as inappropriate

        FWIW, I think this isn't a good idea, because it leads to increased coupling.

        While you could argue that it would only make sense, since C# already has the 'where T : new()' constraint, I would rather argue that the 'new()' constraint never should have been added in the first place. However, now it's too late to remove it, but there's no reason to make things worse.

        For more details, see the section about the Constrained Construction anti-pattern in my book: http://amzn.to/12p90MG

      • Eamon NerbonneEamon 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 PottsTom 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. KingBrannon 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 LippolisGiuseppe 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 GoppeltMarius 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! ;-)

      • CSharpJohnCSharpJohn 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.

      • DavidDavid 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.

      • chhachha commented  ·   ·  Flag as inappropriate

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

        Language: VB.NET

      • Ulrich BuUlrich 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;
        }

      Feedback and Knowledge Base