none
How to constrain a T RRS feed

  • Question

  • I want to define a generic argument T so that is must be some base class (an abstract class I provide) and must also expose a constructor accepting string[].

    It seem this is simply not supported by the language, the only constructor constraint we're allowed is new() - no args.

    An abstract class does not support defining an abstract constructor either which would have helped.

    What are my options to do provide compile time support (rather than runtime reflection based check for such a constructor).

    Thx

    Thursday, September 14, 2017 2:40 AM

All replies

  • I wasn't going to reply to this one, because I was sure someone would have better ideas than me, but as it's been more than two hours...

    The best I can come up with is to create an interface which defines a method that takes a string, use it in each class to do whatever the constructor was supposed to do, then use that interface to constrain the generic argument. Then wherever you were going to call the constructor, instead call the parameterless constructor followed by the interface method.

    Thursday, September 14, 2017 5:07 AM
  • build around the limitation, until that feature is supported:

    create a new layer of base (abstract) class, which only has 1 "constructor accepting string[]"

    then use that as constraint at the generic feature.

    any class intended to be subjected to this generic stuff, must implement this new base class

    Thursday, September 14, 2017 7:15 AM
  • I agree with Ante. I've always just used an abstract Initialize method that accepts the (constructor) parameters. But I tend to shy away from this type of code in general because I think it tends to limit what you can do in derived classes. For example, I cannot "pre-define" a constructor that allows a derived type to set the values accordingly. Example:

    public abstract class MyBase
    {
       protected MyBase ( string name ) { }
    }
    
    public class MyDerived : MyBase
    {
       public MyDerived : base("MyDerived") { }
    }
    
    public T CreateClass<T> ( string name ) where T: MyBase, new()
    {
       //Won't work with MyDerived
       return new T(name); 
    }

    "An abstract class does not support defining an abstract constructor either which would have helped."

    Agreed but constructors are virtual by their very nature. Every type has its own constructors irrelevant of base types (other than the default constructor) so making a constructor virtual wouldn't make sense. In fact virtual calls inside constructors are not a good idea because they don't behave correctly. 

    Michael Taylor
    http://www.michaeltaylorp3.net

    Thursday, September 14, 2017 1:53 PM
    Moderator
  • build around the limitation, until that feature is supported:

    create a new layer of base (abstract) class, which only has 1 "constructor accepting string[]"

    then use that as constraint at the generic feature.

    any class intended to be subjected to this generic stuff, must implement this new base class

    Except constructors are never inherited, you can't declare an abstract constructor.
    Thursday, September 14, 2017 2:51 PM
  • u just create another intermediate layer of base class with the new constructor for the purpose for generic constraint, forget about the abstract, unless u need it.

    as u stated, there is no abstract constructor

    within this new class constructor , u can put in a calling to another abstract method if u want, which functionality will work as like abstract constructor if that's ur intent.


    Wednesday, October 11, 2017 1:41 AM