Jak przekazać parametry do Activator.CreateInstance <T> ()


236

Chcę utworzyć instancję typu określonego przeze mnie w ogólnej metodzie. Ten typ ma wiele przeciążonych konstruktorów. Chciałbym móc przekazywać argumenty konstruktorom, ale

Activator.CreateInstance<T>()

nie widzi tego jako opcji.

Czy jest na to inny sposób?


Odpowiedzi:



16

Istnieje inny sposób przekazywania argumentów do obiektu CreateInstance za pomocą nazwanych parametrów.

Na tej podstawie możesz przekazać tablicę w kierunku CreateInstance. To pozwoli ci mieć 0 lub wiele argumentów.

public T CreateInstance<T>(params object[] paramArray)
{
  return (T)Activator.CreateInstance(typeof(T), args:paramArray);
}

2
To wydaje się niekompletne, na pewno musisz zwrócić obiekt typu T zamiast nieważny? public T CreateInstance <T> (params object [] paramArray) {return (T) Activator.CreateInstance (typeof (T), args: paramArray); }
wlf

11

Pamiętaj jednak, że przekazywanie argumentów na Activator.CreateInstance ma znaczącą różnicę wydajności w porównaniu do tworzenia bez parametrów.

Istnieją lepsze alternatywy dla dynamicznego tworzenia obiektów za pomocą wstępnie skompilowanej lambdy. Oczywiście zawsze wydajność jest subiektywna i wyraźnie zależy od każdego przypadku, czy jest tego warta, czy nie.

Szczegóły dotyczące problemu w tym artykule.

Wykres pochodzi z artykułu i przedstawia czas w ms na 1000 połączeń.

Porównanie wydajności


W kontekście, ta tabela oznacza, że ​​(średnio na tym samym sprzęcie) każde wywołanie sparametryzowanego konstruktora Activator.CreateInstancezajmie 0.0035ms(lub 3,5 mikrosekundy) - w zależności od aplikacji może to nawet nie zarejestrować się w testach wydajności.
Dai

6

Jako alternatywa dla Activator.CreateInstance, FastObjectFactory w połączonym adresie URL działa lepiej niż Activator (od .NET 4.0 i znacznie lepiej niż .NET 3.5. Brak testów / statystyk z .NET 4.5). Zobacz wpis StackOverflow zawierający statystyki, informacje i kod:

Jak przekazać argumenty ctor w Activator.CreateInstance lub użyć IL?


Czy masz na myśli, że istnieje alternatywne rozwiązanie (połączone), które prawdopodobnie będzie działać lepiej niż Activator.CreateInstance podczas przekazywania parametrów? Czy to może działać lepiej we wszystkich przypadkach?
El Zorko,

1
Od jakiegoś czasu nie przeprowadzałem testów wydajności i wygląda na to, że ktoś opublikował statystyki .NET 4.0, ale tak. Z .NET 4.0 wygląda na to, że FastObjectFactory ma lepszą wydajność. Activator.CreateInstance był okropny w .NET 3.5 i był znacznie szybszy w .NET 4.0, jednak nadal wolniejszy niż FastObjectFactory połączony w tym adresie 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;
    }
}

1
Jest to niewyjaśnione tylko kodem. Wątpię, czy to pomaga, a nawet w ogóle działa. Aby mnie przekonać, proszę wyjaśnić, jak to działa i dlaczego ma rozwiązać problem.
Yunnosch
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.