2011-02-02 19 views
5

Mam następujące klasy i próbuję zadzwonić Porównanie metody z klasy ExportFileBaseBL ale pojawia się błądC# rodzajowych - wywołanie metody rodzajowe z ogólnej klasy

nie można niejawnie przekonwertować typu „Class1” na „T” . Wyraźna przemiana istnieje (czy brakuje obsady?)

public abstract class Class1<T> where T: Class2 
{ 
    public abstract Class1<T> Compare(Class1<T> otherObj); 
} 

public abstract class Class3<T, U> where T: Class1<U> 
         where U: Class2 
{ 
    public T Compare(T obj1, T obj2) 
    { 
     if (obj1.Prop1 > obj2.Prop1) 
     { 
      return obj1.Compare(obj2); // Compiler Error here 
     } 
     else 
     { 
      return obj2.Compare(obj1); // Compiler Error here 
     } 
    } 

} 

nie powinien być typu konwersja niejawna? Czy czegoś brakuje?

Odpowiedz

4

Problemem jest to, że metoda jest zdefiniowana streszczenie Compare przyjąć parametr typu Class1<T> i zwracać przykład Class1<T>, nie jest to bardziej specyficzny niż typ niż Class1<T>. Ale to właśnie próbuje wykonać Twoja metoda Class3.Compare: zadzwoń na T.Compare i załóżmy, że wyjście będzie miało postać T, podczas gdy w rzeczywistości możesz być jedynie pewien, że będzie to Class1<U>.

Aby zapewnić prostszy, bardziej zrozumiały przykład, załóżmy, że miałem tę klasę:

class Parser 
{ 
    public abstract object Parse(string text); 
} 

class Int32Parser 
{ 
    public int Parse(Parser parser, string text) 
    { 
     return parser.Parse(text); 
    } 
} 

Powyższy kod sprawia wadliwego założenie podobnego do własnych: że parser.Parse zwróci int tylko dlatego int wywodzi object (tak jak w twoim przypadku, T musi pochodzić z Class1<U>); w rzeczywistości możesz być pewny, że zwróci on object.

Istnieją dwa sposoby widzę, aby rozwiązać ten problem: uczynić Class1<T>.Compare metoda rodzajowa:

public abstract U Compare<U>(U otherObj) where U : Class1<T>; 

... lub zrelaksować specyfikę typ wartości zwrotu Class3.Compare metody badaniem:

public Class1<U> Compare(T obj1, T obj2) 
{ 
    // ... 
} 

Osobiście wolałbym drugi, chyba że absolutnie potrzebujesz pierwszego. Wszystkie te ogólne ograniczenia typu mogą stać się bardzo niechlujne i obciążać cię bardziej, niż się spodziewasz, gdy złożoność zacznie rosnąć w ten sposób.

+0

Dzięki Dan, to odpowiada na moje pytanie. – logik6

+0

Jup Jup, teraz, gdy dodaliśmy aktualizację na temat metody porównywania, zgadzam się z odpowiedzią. – jcolebrand

2

Zadzwoń do metody z typem, który deklarujesz na poziomie twojej klasy.

return obj1.Compare<T>(obj2); 

Musisz sprawić, że definicja z porównania metody rodzajowe, a także:

public abstract Class1<T> Compare<T>(Class1<T> otherObj); 
+1

Metoda Porównaj nie jest generyczna, więc nie zaakceptuje parametru typu w bieżącej formie. –

+0

Ale @Kyle, które po prostu ilustruje, gdzie musi być ustalony w kodzie nadrzędnym. Musi także dodać '' do pierwszej metody porównywania klas. – jcolebrand

+0

Należy to dodać do odpowiedzi. Dodam to. –

Powiązane problemy