Anders Abel
Anders Abel

Reputation: 69260

Constructor requirements on generics parameter?

Looking at this question I started thinking about how to handle constructor requirements in C#.

Assume that I have:

T SomeMethod<T>(string s) : where T : MyInterface
{
    return new T(s);
}

I want to set the requirement on T that it can be constructed out of a string, but as far as I know, constructor definitions are not allowed as part of interfaces. Is there a standard way to solve this?

Upvotes: 3

Views: 208

Answers (3)

Tejs
Tejs

Reputation: 41246

If you want to make it required to have a constructor that takes a string input, you need to implement an abstract class:

public abstract class BaseClass<T>
{
     public BaseClass<T>(string input)
     {
         DoSomething(input);
     }

     protected abstract void DoSomething(string input);
}

Your derived class then simply provides implementation for the abstract method and it can then pick up any interfaces it wants.

public class Sample<T> : BaseClass<T>, IMyInterface
{
    public Sample<T>(string input)
       : base(input)
    {
    }

    protected override void DoSomething(string input)
    {
    }

    public void MyInterfaceMethod()
    {
    }
}

Upvotes: 1

Etienne de Martel
Etienne de Martel

Reputation: 36851

Another way is to dynamically invoke the constructor:

// Incomplete code: requires some error handling
T SomeMethod<T>(string s) : where T : MyInterface
{
    return (T)Activator.CreateInstance(typeof(T), s);
}

The problem with that is that you lose type safety: if you try to use this with a MyInterface implementation that does not have a matching constructor, it will throw an exception.

Upvotes: 2

mathieu
mathieu

Reputation: 31202

Add an init method or a property to your interface,

public interface MyInterface
{
    void Init(string s);
    string S { get; set; }
}

T SomeMethod<T>(string s) : where T : MyInterface, new()
{
    var t = new T();
    t.Init(s);

    var t = new T
    { 
        S = s
    };

    return t;
}

As you can't specify arguments to constructor constraints

Upvotes: 4

Related Questions