2008-09-11 22 views
11

Nie, to nie jest pytanie o generycznych.Aktywator.CreateInstance (ciąg) i Activator.CreateInstance <T>() różnica

Mam wzorzec Factory z kilkoma klasami z wewnętrznymi konstruktorami (nie chcę, aby były tworzone, jeśli nie przez fabrykę).

Mój problem polega na tym, że CreateInstance kończy się niepowodzeniem z błędem "Brak zdefiniowanego bez parametrów konstruktora dla tego obiektu", chyba że przekażę "prawdziwy" parametr niepubliczny.

Przykład

// Fails 
Activator.CreateInstance(type); 

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

Chciałem zrobić fabrykę rodzajowe, aby to trochę prostsze, na przykład:

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

Jednak nie udało mi się znaleźć, jak przekazać, że "prawda" Parametr umożliwiający akceptowanie konstruktorów niepublicznych (wewnętrznych).

Czy coś mi umknęło, czy nie jest to możliwe?

+2

Dlaczego nie definiować konstruktora bez parametrów z prywatnej zmiennej logicznej ustawionej na wartość true? – Vivek

Odpowiedz

20

Aby obejść ten problem, nie mogliśmy po prostu zmienić swoje wykorzystanie jako takie:

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

Twoja metoda fabryka nadal będzie uniwersalne, ale wezwanie do aktywatora nie użyje przeciążenie rodzajowe. Ale nadal powinieneś osiągnąć te same wyniki.

+0

Ładne obejście, ale chciałbym się dowiedzieć, czy to możliwe. – juan

+0

Jeśli przeciążenie nie istnieje, musiałbym powiedzieć "nie". – Kilhoffer

3

Jeśli koniecznie wymagać, że konstruktor być prywatne można spróbować coś takiego:

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

Inaczej jesteś najlepiej wyłączyć dodając nowe ograniczenia i dzieje tej trasie:

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

Ty "Próbujesz użyć GenericFactory jako klasy bazowej dla wszystkich swoich fabryk, zamiast pisać wszystko od zera, prawda?

+0

Pierwsza opcja jest taka sama jak w przypadku Kilhoffera Druga opcja nie działa, dodając nową() do miejsca, w którym typ ma mieć publiczny parametr, który jest dokładnie tym, czego nie chcę – juan

+0

Tak, jego wpis pojawił się, gdy pisałem moje. – rpetrich

0

oprócz Activator.CreateInstance (typeof (T), true) do pracy, T powinna mieć domyślnego konstruktora