2010-02-28 20 views
7

Biorąc pod uwagę następujący kod klient:Czy konstruktor może zwrócić subklasę?

var obj = new Class1(); 

Czy jest jakiś sposób, aby zmodyfikować konstruktor Class1 tak, że będzie faktycznie powrotu podklasę (lub jakąś inną alternatywną implementację) zamiast?

Chciałbym obj, aby uzyskać jedną z dwóch różnych implementacji, w zależności od pewnych warunków. Oczywiście mogłem zmienić na fabryczną lub DI strukturę, ale chciałbym, o ile to możliwe, uniknąć zmiany kodu klienta.

Zakładam, że odpowiedź brzmi nie, ale zastanawiam się, czy jest jakiś sprytny sposób, aby tak się stało.

+4

Rozważamy dodanie funkcji "rozszerzenie nowe", która zasadniczo umożliwiłaby stworzenie statycznej metody fabrycznej, która byłaby wywoływana, gdy używany jest operator "nowy", podobnie jak metody wywoływania są wywoływane, gdy "." operator jest używany. Byłby to ładny cukier syntaktyczny dla fabryki. Jeśli masz naprawdę niesamowity scenariusz, w którym ten rodzaj wzoru byłby przydatny, chciałbym zobaczyć przykład. –

+1

@Eric: chociaż nie jest to konkretny przykład C#, natknąłem się na sytuację, w której byłoby to przydatne w C++. Zajmuję się tworzeniem biblioteki międzyplatformowej i byłoby naprawdę użyteczne, aby agnostyczna platforma ABC mogła zwracać instancję klasy pochodzącą od platformy z jej konstruktora. Jestem pewien, że muszą być podobne sytuacje, które można znaleźć podczas pracy z C#. – Mac

+0

@Eric Lippert - Mam dla Ciebie scenariusz w prawdziwym świecie! http://blog.hackensplat.com/2010/09/construct-something-else-c.html – billpg

Odpowiedz

4

To nie jest możliwe.

Sprytne obejścia obejmują zastąpienie konstruktora funkcją static lub (niezalecane) za pomocą obwoluty wokół klasy bazowej i tworzenie różnych klas zawijanych.

8

Można wymienić konstruktor z metody fabryki i powrót co chcesz, w zależności od parametrów:

public Class2 : Class1 {} 

public static Class1 CreateClass1(bool returnDerivedClass) 
{ 
    if (returnDerivedClass) 
    { 
     return new Class2(); 
    } 
    else 
    { 
     return new Class1(); 
    } 
} 
0

rzeczy takie jak chcesz sprawdzić wzór fabryczne. Ponadto, w zależności od potrzeb, polecam zapoznanie się z ogólnymi metodami redukcji sprzężenia. Twoje połączenie z konstruktorem klasy jest najtrudniejszym sprzężeniem, jakie możesz mieć w programie i sprawia, że ​​wymienianie implementacji staje się kłopotliwe, gdy sam się o tym dowiesz.

Przeczytaj o "Inwersji kontroli" i "Dependency Injection", może tego właśnie szukasz.

Przyjemną bibliotekę można znaleźć pod numerem here.

0

Użyj biblioteki do wstrzykiwań. poniżej link prezentuje wielką listę bibliotek wtryskowych tam i porównanie ich wyników

http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

Sugerowałbym jednak, że wydajność jest rzadko kryteria wybrałbyś biblioteki wtrysku na większość aplikacji nie instancję liczba przedmiotów, które ten facet wykorzystał w swoich testach. Używam NInject, który wykonuje to zadanie dobrze, jednak gdybym zaczął inny projekt, prawdopodobnie dałbym mu wszystkie funkcje, które używam w NInject i sprawdza się w porównaniach wydajności.

Powiązane problemy