Como passar parâmetros para Activator.CreateInstance <T> ()

236

Quero criar uma instância de um tipo que especifique em um método genérico que possuo. Esse tipo possui vários construtores sobrecarregados. Eu gostaria de poder passar argumentos para os construtores, mas

Activator.CreateInstance<T>()

não vê isso como uma opção.

tem outro jeito de fazer isto?

DaveDev
fonte

Respostas:

458

Sim.

(T)Activator.CreateInstance(typeof(T), param1, param2);
SLaks
fonte
2
Eu gosto desta resposta ;-)
frhack
16

Há outra maneira de passar argumentos para CreateInstance através de parâmetros nomeados.

Com base nisso, você pode passar uma matriz para CreateInstance. Isso permitirá que você tenha 0 ou vários argumentos.

public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}
sudhAnsu63
fonte
2
Isso parece incompleto, certamente você precisa retornar um objeto do tipo T em vez de nulo? public T CreateInstance <T> (objeto de parâmetro [] paramArray) {return (T) Activator.CreateInstance (typeof (T), args: paramArray); }
wlf
11

Lembre-se de que a transmissão de argumentos no Activator.CreateInstance tem uma diferença significativa de desempenho em relação à criação sem parâmetros.

Existem alternativas melhores para criar objetos dinamicamente usando lambda pré-compilado. É claro que sempre o desempenho é subjetivo e depende claramente de cada caso, se vale a pena ou não.

Detalhes sobre o problema neste artigo.

O gráfico é retirado do artigo e representa o tempo gasto em ms por 1000 chamadas.

Comparação de desempenho

Anestis Kivranoglou
fonte
Por contexto, esse gráfico significa que (em média, no mesmo hardware) cada chamada de um construtor parametrizado Activator.CreateInstancelevará 0.0035ms(ou 3,5 microssegundos) - dependendo do seu aplicativo, isso pode até não ser registrado em testes de desempenho.
Dai
6

Como alternativa ao Activator.CreateInstance, FastObjectFactory no URL vinculado é melhor que o Activator (a partir do .NET 4.0 e significativamente melhor que o .NET 3.5. Não foram realizados testes / estatísticas com o .NET 4.5). Veja a publicação StackOverflow para estatísticas, informações e código:

Como passar ctor args no Activator.CreateInstance ou usar IL?

Tamisa
fonte
Você quer dizer que existe uma solução alternativa (vinculada) que provavelmente terá um desempenho melhor que o Activator.CreateInstance ao passar parâmetros? Ou é provável que tenha um desempenho melhor em todos os casos?
El Zorko 20/01
1
Eu não faço testes de desempenho há algum tempo e parece que alguém postou estatísticas do .NET 4.0, mas sim com o .NET 4.0 parece que o FastObjectFactory tem melhor desempenho. O Activator.CreateInstance foi horrível no .NET 3.5 e foi significativamente mais rápido no .NET 4.0, mas ainda mais lento que o FastObjectFactory vinculado nesse URL.
Thames
1
public class AssemblyLoader<T>  where T:class
{
    public void(){
        var res = Load(@"C:\test\paquete.uno.dos.test.dll", "paquete.uno.dos.clasetest.dll") 
    }

    public T Load(string assemblyFile, string objectToInstantiate) 
    {
        var loaded = Activator.CreateInstanceFrom(assemblyFile, objectToInstantiate).Unwrap();

        return loaded as T;
    }
}
Carga dinamica de dll
fonte
1
Isso é apenas um código inexplicável. Duvido que ajude ou até funcione. Para me convencer do contrário, explique como isso funciona e por que ele deve resolver o problema.
Yunnosch 03/04