5 Stimmen

Kann ich eine implementierende Klasse zwingen, ein Objekt ihres eigenen Typs zurückzugeben?

Ich möchte eine Schnittstelle in C# erstellen, die eine Methode definiert, die immer ein Objekt der implementierenden Klasse zurückgibt, also:

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 dazu zwingen, ein Objekt ihres eigenen Typs zurückzugeben? Wenn möglich, dann wie ? Oder sind Generika hier die Antwort?

NB: Der Code dient nur zur Veranschaulichung und ist nicht bindend. laufen soll.

8voto

BennyM Punkte 2698

Generika sind hier die Antwort.

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

5voto

FacticiusVir Punkte 2017

Nicht in der Schnittstellendeklaration, nein. Das Beste, was Sie tun 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);
    }
}

Das bedeutet nicht Kraft die Implementierung, ihren eigenen Typ zurückzugeben, aber zumindest erlaubt sie es ihr, dies zu tun. Aus diesem Grund ist die IClonable Schnittstelle gibt ein Objekt aus ihrer Clone Methode und nicht auf einen bestimmten Typ.

----Bearbeiten----

Etwas, das Sie sich bei dieser Frage merken sollten: Nehmen wir an, dass mein Code, für den Sie keine Kenntnisse über die Implementierung haben, eine IParser auf, und Ihr Code ruft die Parse Methode. Welches Objekt erwarten Sie zurück, wenn Sie den konkreten Typ des zurückgegebenen Objekts nicht kennen? IParser Referenz? Ich glaube, Sie versuchen, Schnittstellen für etwas zu verwenden, wofür sie nicht gedacht sind...

1voto

Konamiman Punkte 48557

Ja, und das ist bekannt als das Fabrikmuster Nur wird dies in der Regel durch die Verwendung eines privaten Konstruktors und die statische Rückgabemethode der Instanz ergänzt:

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

0voto

tvanfosson Punkte 506878

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 als auch sein.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X