ProfK
ProfK

Reputation: 51063

What's with instantiating from a type parameter T not allowing constructor aguments?

If I have classes:

class Useless
{
    private string _message ;
    public Useless(string message)
    {
        _message = message;
    }
}

class UselessFactory<T> where T : new()
{
    public Useless CreateUseless(string msg)
    {
        return new T(msg);
    }
}

Why can't I instantiate T with parameters, like I could do with the following?

return (Useless)Activator.CreateInstance(typeof(T), msg);

Upvotes: 1

Views: 90

Answers (3)

Martin Mulder
Martin Mulder

Reputation: 12944

It is simply not supported at this moment.

There are work arounds:

  • Mark the type T with an interface or class (where T: MyClass) and set properties or call its methods to initialize the instance.
  • Your Activator.Activate (a slow dynamic method).
  • The fastest dynamic method is to once use reflection to find the correct ConstructorInfo and convert this into a strongly typed delegate (in your case: Func<string, T>). You can call this delegate which will construct an instance with the given parameter.

Upvotes: 1

Johan Larsson
Johan Larsson

Reputation: 17580

The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor.

From the docs

Possible workaround (not the same thing)

If you make Message a public and mutable property you can do:

class UselessFactory<T> where T : UselessBase, new()
{
    public T CreateUseless(string msg)
    {
        return new T() { Message = msg };
    }
}

Upvotes: 2

user1522991
user1522991

Reputation:

You could do the following:

return (T)Activator.CreateInstance(typeof(T), new object[] { msg });

I got it from this question: https://stackoverflow.com/a/731637/1522991

Upvotes: 1

Related Questions