Diferença entre Activator.CreateInstance(string) e Activator.CreateInstance<T>()
-
09-06-2019 - |
Pergunta
Não, esta não é uma pergunta sobre genéricos.
Tenho um padrão Factory com diversas classes com construtores internos (não quero que eles sejam instanciados senão através da fábrica).
Meu problema é que CreateInstance
falha com um erro "Nenhum construtor sem parâmetros definido para este objeto", a menos que eu passe "true" no parâmetro não público.
Exemplo
// Fails
Activator.CreateInstance(type);
// Works
Activator.CreateInstance(type, true);
Eu queria tornar a fábrica genérica para torná-la um pouco mais simples, assim:
public class GenericFactory<T> where T : MyAbstractType
{
public static T GetInstance()
{
return Activator.CreateInstance<T>();
}
}
No entanto, não consegui descobrir como passar esse parâmetro "true" para aceitar construtores não públicos (internos).
Perdi alguma coisa ou não é possível?
Solução
Para contornar isso, você não poderia simplesmente alterar seu uso da seguinte forma:
public class GenericFactory<T> where T : MyAbstractType
{
public static T GetInstance()
{
return Activator.CreateInstance(typeof(T), true);
}
}
Seu método de fábrica ainda será genérico, mas a chamada ao ativador não usará a sobrecarga genérica.Mas você ainda deve alcançar os mesmos resultados.
Outras dicas
Se você realmente precisa que o construtor seja privado, você pode tentar algo assim:
public abstract class GenericFactory<T> where T : MyAbstractType
{
public static T GetInstance()
{
return (T)Activator.CreateInstance(typeof(T), true);
}
}
Caso contrário, é melhor adicionar a nova restrição e seguir esse caminho:
public abstract class GenericFactory<T> where T : MyAbstractType, new()
{
public static T GetInstance()
{
return new T;
}
}
Você está tentando usar GenericFactory como classe base para todas as suas fábricas, em vez de escrever cada uma do zero, certo?
além de Activator.CreateInstance(typeof(T), true) funcionar, T deve ter construtor padrão