2009-11-06 7 views
5

ich eine Schnittstelle in C# machen wollen, das ein Verfahren definiert, das immer ein Objekt der implementierenden Klasse zurückgibt, also:Kann ich eine implementierende Klasse zwingen, ein Objekt seines eigenen Typs zurückzugeben?

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

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

Kann ich eine implementierende Klasse zwingen, ein Objekt von seiner eigenen Art zurückzukehren? Wenn möglich, dann wie? Oder ist Generika die Antwort hier?

NB: Der Code ist nur eine Darstellung, nicht etwas, das angenommen hat, laufen.

+0

Du hast mich sehr neugierig gemacht: Warum versuchst du das zu tun? Im Allgemeinen ist der Punkt, an dem eine Schnittstelle definiert wird, so, dass Client-Code darauf vertrauen kann, dass eine bestimmte API für ein Objekt definiert ist, ohne dass Sie wissen oder sich darum kümmern müssen, welcher konkrete Typ dieses Objekts ist. Das ist eine der großen Stärken von OOP. Was versuchst du damit zu erreichen? –

+0

Nun, mein Gedanke war, dass Sie mit dieser Schnittstelle immer darauf vertrauen können, dass die Klassen, die die Schnittstelle implementieren, diese Methode haben und dass sie immer ihren eigenen Typ zurückgeben werden. Aber wie du sagst, ist dies vielleicht nicht das beste OO-Design und ich werde es für eine Methode aufgeben, die stattdessen den Interface-Typ zurückgibt. – Cros

Antwort

8

Generics ist die Antwort Hier.

+0

Gute Arbeit ... Ich habe gerade meinen Code für dasselbe getestet. +1 – jheddings

+0

Ich werde das sofort versuchen. – Cros

+0

Scheint, dass, wenn Sie die Schnittstelle so generisch machen, Sie T angeben müssen, wo Sie ISelection als Spezifizierer für den Typ verwenden, den Sie verwenden, z. Ich kann jetzt nicht nur eine Liste machen, aber jetzt muss es eine Liste sein >. Hab ich recht? Dann ist das nicht die Lösung, nach der ich suche, leider. – Cros

1

Ja, und dies wird als the factory pattern bekannt, nur, dass dies in der Regel mit der Verwendung eines privaten Konstruktor ergänzt und macht die Instanz-Methode statisch Rückkehr, zum Beispiel:

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

Ich denke, der Schlüssel ist die Phrase "... erzwinge eine implementierende Klasse, um ein Objekt seines eigenen Typs zurückzugeben ..." –

+0

Dies war wirklich keine "Ja/Nein" -Frage. Ich möchte konkret wissen, wie dies in C# getan wird, wenn es möglich ist. – Cros

0

Sie können dies mit Generics tun, aber ich würde wahrscheinlich mit der Rückgabe einer Instanz der Schnittstelle bleiben. Beachten Sie, dass, da die Klasse die Schnittstelle implementiert, die Rückgabe einer Instanz davon in Ordnung ist - es wird eine Instanz dieses Typs und der Schnittstelle sein.

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

Nicht in der Schnittstellendeklaration, nein. Das Beste, was Sie verwalten können, ist mit Generika:

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

Dies gilt nicht Kraft die Umsetzung zurück es eigene Art ist, aber zumindest ist es erlaubt es, dies zu tun. Aus diesem Grund gibt die Schnittstelle IClonable anstelle eines bestimmten Typs ein Objekt aus der Clone-Methode zurück.

---- ---- bearbeiten

Etwas über diese Frage zu erinnern: lassen Sie uns sagen, dass mein Code, für die Sie keine Kenntnisse über die Implementierung haben, eine IParser zurückgibt, und der Code ruft die Parse Methode auf. Welches Objekt erwarten Sie zurückgegeben werden, nicht den konkreten Typ der zurückgegebenen IParser Referenz kennen? Ich denke, du versuchst, Schnittstellen für etwas zu verwenden, das sie nicht tun sollen ...

+1

+1 für die Erwähnung dieser Technik erzwingt nicht die angeforderte Implementierung. Sie könnten ebenso einfach eine andere IParser-Implementierung zurückgeben. AFAIK gibt es keine Möglichkeit, diese Prüfung auf Sprachenebene durchzusetzen; Das ist das nächste, was du damit erreichen wirst. –

Verwandte Themen