juan
juan

Reputation: 82014

Activator.CreateInstance(string) and Activator.CreateInstance<T>() difference

No, this is not a question about generics.

I have a Factory pattern with several classes with internal constructors (I don't want them being instantiated if not through the factory).

My problem is that CreateInstance fails with a "No parameterless constructor defined for this object" error unless I pass "true" on the non-public parameter.

Example

// Fails
Activator.CreateInstance(type);

// Works
Activator.CreateInstance(type, true);

I wanted to make the factory generic to make it a little simpler, like this:

public class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return Activator.CreateInstance<T>();
    }
}

However, I was unable to find how to pass that "true" parameter for it to accept non-public constructors (internal).

Did I miss something or it isn't possible?

Upvotes: 11

Views: 22222

Answers (3)

mpastern
mpastern

Reputation: 1

besides Activator.CreateInstance(typeof(T), true) to work, T should have default constructor

Upvotes: 0

Kilhoffer
Kilhoffer

Reputation: 32924

To get around this, couldnt you just alter your usage as such:

public class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return Activator.CreateInstance(typeof(T), true);
    }
}

Your factory method will still be generic, but the call to the activator will not use the generic overload. But you should still achieve the same results.

Upvotes: 21

rpetrich
rpetrich

Reputation: 32346

If you absolutely require that the constructor be private you can try something like this:

public abstract class GenericFactory<T> where T : MyAbstractType
{
    public static T GetInstance()
    {
        return (T)Activator.CreateInstance(typeof(T), true);
    }
}

Otherwise you're best off adding the new constraint and going that route:

public abstract class GenericFactory<T> where T : MyAbstractType, new()
{
    public static T GetInstance()
    {
        return new T;
    }
}

You're trying to use GenericFactory as a base class for all of your factories rather than writing each from scratch right?

Upvotes: 3

Related Questions