2008-10-24 49 views
7

Tôi có class A:contraints Generic trên các lớp thừa kế

public class ClassA<T> 

Class B xuất phát từ A:

public class ClassB : ClassA<ClassB> 

Loại C có nguồn gốc từ lớp B:

public class ClassC : ClassB 

Bây giờ tôi có một phương pháp chung với các ràng buộc

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

OK, bây giờ tôi muốn gọi:

ClassC c = Method<ClassC>(); 

nhưng tôi nhận được lỗi biên dịch nói: Type argument 'ClassC' does not inherit from or implement the constraint type 'ClassA<ClassC>.

Tuy nhiên, các trình biên dịch sẽ cho phép:

ClassB b = Method<ClassB>(); 

hiểu biết của tôi là điều này không thành công vì ClassC thừa hưởng ClassA<ClassB> thay vì ClassA<ClassC>

câu hỏi thực sự của tôi là, là nó có thể tạo ra một lớp bắt nguồn từ ClassB có thể được sử dụng trong một cách nào đó với phương pháp chung chung?

Điều này có vẻ như generics bị lạm dụng và tôi đồng ý. Tôi đang cố gắng để tạo ra các đối tượng lớp kinh doanh xuất phát từ các đối tượng dữ liệu cận âm trong một dự án riêng biệt.

Lưu ý: Tôi đã đặt < T> có thêm khoảng trống nếu không chúng sẽ bị tước khỏi câu hỏi.

Trả lời

5

Vâng, bạn có thể thay đổi phương pháp để:

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

Điều đó giúp đỡ ở tất cả? Nó không được sử dụng nhiều nếu bạn không thể thay đổi phương pháp tất nhiên ...

+0

Đúng, điều này giải quyết được sự cố. Phương pháp này thực sự là: DB.Get < T > (string primaryColumnValue) T sử dụng để trả về một đối tượng dữ liệu từ cơ sở dữ liệu. Nó cảm thấy như nó đang trở nên phức tạp hơn mà nó cần phải được ... Tôi cần phải quay trở lại và suy nghĩ lại về kiến ​​trúc. – ptutt

2

No. Bạn phải thay đổi hoặc bọc phương pháp này.

Đây là lý do.

ClassC được thừa hưởng từ ClassB mà kế thừa từ ClassA (ClassB)

ClassC không kế thừa từ ClassA (ClassC)

Không con của ClassB sẽ kế thừa từ ClassA (lớp trẻ), bởi vì họ thay vì kế thừa từ ClassB và ClassB không kế thừa từ ClassA (lớp con).

Generic types are invariant.

1

Trong hầu hết các trường hợp chúng ta có thể giải quyết tình huống này bằng cách có một lớp cơ sở trừu tượng phi generic:

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

Mileage của bạn có thể thay đổi, mặc dù.

+0

Trong trường hợp này, đề xuất này không giải quyết được tình huống vì trong phương thức "Phương pháp" được gọi trên ClassA mà kiểu trả về T. Cảm ơn bạn đã gợi ý. – ptutt

Các vấn đề liên quan