2011-02-02 35 views
5

Tôi có các lớp sau đây và tôi đang cố gắng để gọi Hãy so sánh phương pháp từ lớp ExportFileBaseBL nhưng tôi nhận được lỗiC# Generics - Việc gọi method generic từ một lớp generic

Không thể ngầm chuyển đổi loại 'Class1' thành 'T' . Một chuyển đổi rõ ràng tồn tại (bạn có bỏ lỡ một dàn diễn viên không?)

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 
     } 
    } 

} 

Không nên chuyển đổi loại? Tui bỏ lỡ điều gì vậy?

Trả lời

4

Vấn đề là rằng phương pháp trừu tượng Compare của bạn được xác định để chấp nhận một tham số kiểu Class1<T> và trả lại thể hiện của Class1<T>, không phải là cụ thể hơn loại hơn Class1<T>. Nhưng đây là phương pháp Class3.Compare của bạn đang cố gắng thực hiện: gọi T.Compare và giả định đầu ra sẽ là T, trong thực tế bạn chỉ có thể chắc chắn nó sẽ là Class1<U>.

Để cung cấp một đơn giản, ví dụ dễ hiểu hơn, cho rằng tôi có lớp học này:

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

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

Đoạn mã trên tạo ra một giả thuyết bị lỗi tương tự như của riêng bạn: đó parser.Parse sẽ trả về một int chỉ vì int xuất phát từ object (giống như trong trường hợp của bạn, T phải xuất phát từ Class1<U>); trên thực tế, bạn chỉ có thể chắc chắn rằng nó sẽ trả về một số object.

Có hai cách tôi có thể thấy để khắc phục vấn đề này: làm Class1<T>.Compare một phương pháp chung:

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

... hoặc thư giãn kiểu đặc trưng của giá trị trả về Class3.Compare phương pháp của bạn:

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

Cá nhân, tôi thích thứ hai trừ khi bạn hoàn toàn cần thứ nhất. Tất cả những ràng buộc kiểu chung này có thể trở nên rất lộn xộn và đè nặng bạn nhiều hơn bạn mong đợi khi sự phức tạp bắt đầu phát triển như thế này.

+0

Cảm ơn Dan, câu trả lời cho câu hỏi của tôi. – logik6

+0

Jup jup, bây giờ chúng tôi đã thêm một cập nhật về cách gõ so sánh, tôi đồng ý với câu trả lời. – jcolebrand

2

Gọi phương thức với loại thông số bạn khai báo ở cấp lớp của bạn.

return obj1.Compare<T>(obj2); 

Bạn sẽ cần phải thực hiện định nghĩa của phương pháp so sánh chung chung cũng như:

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

Phương pháp so sánh không phải là chung chung, do đó, nó sẽ không chấp nhận thông số loại ở dạng hiện tại của nó. –

+0

Nhưng @Kyle chỉ minh họa nơi cần được sửa trong mã gốc. Anh ta cũng cần thêm một '' vào phương thức so sánh lớp đầu tiên. – jcolebrand

+0

Điều đó sẽ được thêm vào câu trả lời sau đó. Tôi sẽ thêm nó. –