2009-11-06 32 views
5

Tôi muốn làm một giao diện trong C# định nghĩa một phương pháp mà luôn luôn trả về một đối tượng của lớp thực hiện, như sau:Tôi có thể buộc một lớp thực hiện trả về một đối tượng thuộc kiểu riêng của nó không?

public interface IParser { 
    IParser Parse(string s); 
} 

public class Parser : IParser { 
    public Parser Parse(string s) { 
     return new Parser(s); 
    } 
} 

Tôi có thể buộc một lớp thực hiện để trả lại một đối tượng kiểu riêng của mình? Nếu có thể, sau đó cách? Hay là generics câu trả lời ở đây?

NB: Mã này chỉ là một minh hoạ, không phải cái gì đó là phải chạy.

+0

Bạn đã khiến tôi rất tò mò: tại sao bạn lại cố gắng làm điều này? Nói chung, điểm xác định một giao diện là để mã máy khách có thể tin tưởng rằng một API nhất định được định nghĩa trên một đối tượng mà không cần phải biết hoặc quan tâm đến loại cụ thể của đối tượng đó. Đó là một trong những thế mạnh lớn của OOP. Điều gì mà bạn đang cố gắng thực hiện bằng cách làm điều này? –

+0

Vâng, suy nghĩ của tôi là khi có giao diện này, bạn luôn có thể tin tưởng rằng các lớp thực hiện giao diện sẽ có phương thức này và chúng sẽ luôn trả về kiểu của riêng chúng. Nhưng như bạn nói, đây có thể không phải là thiết kế OO tốt nhất và tôi sẽ từ bỏ nó cho một phương thức trả về kiểu giao diện thay thế. – Cros

Trả lời

8

Generics là câu trả lời đây.

public interface IParser<T> where T:IParser<T> { 
    T Parse(string s); 
} 

public class Parser : IParser<Parser> { 
    public Parser Parse(string s) { 
     return new Parser(s); 
    } 
} 
+0

Làm tốt lắm ... Tôi vừa kiểm tra mã của tôi cho cùng một thứ. +1 – jheddings

+0

Tôi sẽ thử ngay lập tức. – Cros

+0

Dường như khi bạn tạo giao diện chung như thế này, bạn phải chỉ định T ở mọi nơi bạn sử dụng ISelection làm thông số cho loại bạn sử dụng, ví dụ: Hiện tại, tôi không thể tạo Danh sách nhưng bây giờ nó phải là Danh sách >. Tôi có đúng không? Sau đó, đây không phải là giải pháp tôi đang tìm kiếm, thật đáng buồn. – Cros

1

Vâng, và điều này được gọi là the factory pattern, duy nhất mà thường này được bổ sung với việc sử dụng một constructor tin và làm cho các trường hợp phương pháp trở về tĩnh, ví dụ:

public class Parser : IParser { 

    private Parser(string s) { 
     //Do something with s, probably store it in a field 
    } 

    public static IParser GetNewParser(string s) { 
     return new Parser(s); 
    } 
} 
+0

Tôi nghĩ chìa khóa là cụm từ "... buộc một lớp thực hiện trả về một đối tượng thuộc loại riêng của nó ..." –

+0

Đây thực sự không phải là câu hỏi "có/không". Tôi muốn cụ thể biết làm thế nào điều này được thực hiện trong C#, nếu có thể. – Cros

0

Bạn có thể làm điều này với Generics, nhưng có lẽ tôi sẽ gắn bó với việc trả về một thể hiện của giao diện. Lưu ý rằng kể từ khi lớp thực hiện giao diện, trả về một thể hiện của nó là ok - nó sẽ là một thể hiện của kiểu đó và của giao diện là tốt.

public class Parser : I Parser 
{ 
    public IParser Parser(string s) 
    { 
     return Parser(s); 
    } 
} 
5

Không có trong khai báo giao diện, không. Điều tốt nhất bạn có thể quản lý là với Generics:

public interface IParser<T> 
    where T: IParser<T> 
{ 
    T Parse(string s); 
} 

public class Parser 
: IParser<Parser> 
{ 
    public Parser Parse(string s) 
    { 
     return new Parser(s); 
    } 
} 

này không lực việc thực hiện trở lại đó là loại riêng, nhưng ít nhất nó cho phép nó làm như vậy. Đây là lý do tại sao giao diện IClonable trả về một đối tượng từ phương thức Clone của nó, chứ không phải là một loại cụ thể.

---- Sửa ----

cái gì đó để nhớ về câu hỏi này: giả sử rằng mã của tôi, mà bạn không có bất kỳ kiến ​​thức về việc thực hiện, trả về một IParser, và mã của bạn gọi phương thức Parse. Đối tượng nào bạn mong đợi được trả lại, không biết loại tham chiếu IParser được trả về cụ thể nào? Tôi nghĩ bạn đang cố gắng sử dụng giao diện cho những thứ họ không muốn làm ...

+1

+1 để đề cập đến kỹ thuật này không bắt buộc thực hiện được yêu cầu. Bạn có thể dễ dàng trả lại một thực thi IParser khác. AFAIK không có cách nào để thực thi kiểm tra này ở cấp độ ngôn ngữ; đây là điều gần nhất bạn sẽ đạt được. –

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