2010-04-22 40 views
6

Đáp ứng một vấn đề lạ ở phép tính nói rằng một lớp không thực hiện một giao diện.Giao diện triển khai lớp chung không thành công

Hãy nói một câu có một lớp:

public Class MyClass 
{ 
... 
} 

Và một interace:

public Interface IMyInterface 
{ 
MyClass PropertyOfMyClass {get;} 
} 

và bây giờ là một lớp chung:

public class MyGeneric<T> where T:MyClass 
{ 
    T PropertyOfMyClass 
    { 
    get{return ...;} 
    } 
} 

Cho đến đây Everythings tốt và biên dịch đúng.

Nhưng điều này sẽ phá vỡ lúc biên soạn:

public class MyGeneric<T>:IMyInterace where T:MyClass 
    { 
     T PropertyOfMyClass 
     { 
     get{return ...;} 
     } 
    } 

Nói rằng MyGeneric không làm dụng cụ phương pháp IMyInterface. Nhưng rõ ràng là vậy, phải không?

+0

Nghĩ rằng tôi không hiểu là nếu T là loại hoặc hậu duệ của MyClass thì tài sản T PropertyOfMyClass bằng với MyClass PropertyOfMyClass. Vậy tại sao điều này không biên dịch? – Pitming

Trả lời

6

Bạn không thể triển khai thuộc tính (hoặc phương thức) từ giao diện có phương sai. Điều này không chỉ ảnh hưởng đến Generics. Ví dụ:

public interface IFoo 
{ 
    object Bar(); 
} 

public class Foo : IFoo 
{ 
    // This won't compile 
    string Bar() { return "hello"; } 
} 

Bây giờ bạn có thể nhận được vòng này với thực hiện giao diện rõ ràng:

public class Foo : IFoo 
{ 
    // Make the interface implementation call the more strongly-typed method 
    object IFoo.Bar() { return Bar(); } 

    string Bar() { return "hello"; } 
} 

Đó có thể là một câu trả lời cho bạn - hay có thể không. Chúng tôi cần biết chính xác lý do bạn muốn khai báo thuộc tính là loại T thay vì chỉ MyClass để biết chắc chắn.

+0

Tôi không muốn trả về một phiên bản MyClass vì tôi đã có phân cấp đầy đủ trong lớp của tôi và lớp chung trả về cho tôi lớp đúng mà không cần truyền. – Pitming

1

workaround khác sẽ làm cho giao diện chung thân:

public interface IMyInterface<T> where T : MyClass 
{ 
    T PropertyOfMyClass { get; } 
} 

Sau đó, bạn có thể sử dụng nó trên một lớp:

public class MyGenericClass<T> : IMyInterface<T> where T : MyClass 
{ 
    T PropertyOfMyClass 
    { 
     get { ... } 
    } 
} 

Lưu ý rằng việc sử dụng thực hiện này, các hạn chế về T trong lớp chung có thể khác với lớp trên giao diện, miễn là đảm bảo ràng buộc giao diện được tôn trọng:

public class MyOtherClass : MyClass 
{ 
} 

public class MyOtherGenericClass<T> : IMyInterface<T> where T : MyOtherClass 
{ 
    T PropertyOfMyClass 
    { 
     get { ... } 
    } 
} 
+0

Tất nhiên, nhưng giao diện của tôi có thể không trở thành chung ... – Pitming

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