2008-10-24 11 views
7

mam klasy A:ogólne contraints na klasy pochodnych

public class ClassA<T> 

Klasa B pochodzi od:

public class ClassB : ClassA<ClassB> 

klasy C pochodzi z klasy B:

public class ClassC : ClassB 

Teraz mam metoda rodzajowa z ograniczeniami

public static T Method<T>() where T : ClassA<T> 

OK, teraz chcę zadzwonić:

ClassC c = Method<ClassC>(); 

ale pojawia się błąd kompilacji mówiąc: Type argument 'ClassC' does not inherit from or implement the constraint type 'ClassA<ClassC>.

Jeszcze, kompilator pozwoli:

ClassB b = Method<ClassB>(); 

Rozumiem, że to się nie powiedzie, ponieważ ClassC dziedziczy ClassA<ClassB> zamiast ClassA<ClassC>

Moje pytanie brzmi, czy jest możliwe, aby utworzyć klasę wynikającą z ClassB, które można wykorzystać w jakiś sposób z metody rodzajowe?

Może się wydawać, że generics są nadużywane i zgadzam się. Próbuję tworzyć warstwy biznesowe obiektów pochodzących z poddźwiękowych obiektów danych w oddzielnym projekcie.

Uwaga: Umieściłem < T> z dodatkowymi odstępami, w przeciwnym razie zostaną one usunięte z pytania.

Odpowiedz

5

Cóż, można zmienić metodę na:

public static T Method<T,U>() where T : ClassA<U> where U : T 

Czy to pomoc w ogóle? Nie ma sensu, jeśli nie możesz zmienić Sposób oczywiście ...

+0

Tak, to rozwiązuje problem. Metoda jest następująca: DB.Get < T > (string primaryColumnValue) T służy do zwrócenia obiektu danych z bazy danych. Wydaje się, że jest coraz bardziej skomplikowane, że musi być ... Muszę się cofnąć i przemyśleć ponownie o architekturze. – ptutt

2

Nie. Musisz zmienić lub zawinąć tę metodę.

Oto powód.

ClassC dziedziczy ClassB która dziedziczy z ClassA (ClassB)

ClassC nie dziedziczy z ClassA (ClassC)

No dzieckiem ClassB odziedziczy od ClassA (klasa dziecko), ponieważ zamiast dziedziczyć Klasa B i klasa B nie dziedziczą z klasy A (klasa podrzędna).

Generic types are invariant.

1

W większości przypadków jest to możliwe, aby rozwiązać ten scenariusz za posiadające podstawę nierodzajową klasy abstrakcyjnej:

public abstract class BasicClassA 
{ 
} 

public class ClassA<T> : BasicClassA 
{ 
} 

public class ClassB : ClassA<ClassB> 
{ 
} 

public class ClassC : ClassB 
{ 
} 

public static T Method<T>() where T : BasicClassA 
{ 
    return null; 
} 

Twój przebieg mogą się różnić, choć.

+0

W tym przypadku ta sugestia nie rozwiązuje scenariusza, ponieważ w metodach "Method" są wywoływane w ClassA , które zwracają typ T. Dzięki za sugestię. – ptutt