2014-05-12 12 views
6

Trong ví dụ sau, tôi có hai ràng buộc, FoobarIFoobar<T>, trên loại T trong lớp chung FoobarList<T>. Nhưng trình biên dịch đưa ra một lỗi: Không thể chuyển đổi hoàn toàn kiểu 'Foobar' thành 'T'. Một chuyển đổi rõ ràng tồn tại (là bạn thiếu một dàn diễn viên?)Mức độ ưu tiên của nhiều ràng buộc đối với tham số kiểu chung

interface IFoobar<T> 
{ 
    T CreateFoobar(); 
} 

class Foobar : IFoobar<Foobar> 
{ 
    //some foobar stuffs 
    public Foobar CreateFoobar() { return new Foobar(); } 
} 

class FoobarList<T> where T : Foobar, IFoobar<T> 
{ 
    void Test(T rFoobar) 
    { 
     T foobar = rFoobar.CreateFoobar(); //error: cannot convert Foobar to T 
    } 
} 

Dường như trình biên dịch coi CreateFoobar như một phương pháp trong Foobar, nhưng không phải là một trong IFoobar. Tôi có thể sửa chữa các biên dịch bằng cách chia Foobar thành một FoobarBase lớp cơ sở, và thực hiện IFoobar giao diện trong lớp có nguồn gốc của nó, như sau:

interface IFoobar<T> 
{ 
    T CreateFoobar(); 
} 

abstract class FoobarBase 
{ 
    //some foobar stuffs 
} 

class Foobar : FoobarBase, IFoobar<Foobar> 
{ 
    public Foobar CreateFoobar() { return new Foobar(); } 
} 

class FoobarList<T> where T : FoobarBase, IFoobar<T> 
{ 
    void Test(T rFoobar) 
    { 
     T foobar = rFoobar.CreateFoobar(); 
    } 
} 

Đó là cồng kềnh để chia Foobar thành hai lớp. Có cách nào tốt hơn để sửa lỗi này không?

+1

Việc triển khai giao diện có giúp rõ ràng không? – Rotem

Trả lời

4

Chỉ cần đúc rFoobar để IFoobar<T>:

T foobar = ((IFoobar<T>)rFoobar).CreateFoobar(); 

Bằng cách đó bạn đang gọi điện thoại một phương thức trả T thay vì chỉ Foobar.

Như Rotem gợi ý, thay đổi phương pháp trong Foobar sử dụng thực hiện giao diện rõ ràng làm việc quá:

Foobar IFoobar<Foobar>.CreateFoobar() { return new Foobar(); } 

Bằng cách đó phương pháp đó sẽ không thể được tìm thấy trong T, vì vậy một lần nữa nó sẽ giải quyết cho phương thức giao diện.

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