2009-11-06 10 views
5

chcę zrobić interfejs w języku C#, który określa metodę, która zawsze zwraca obiekt klasy wykonawczego, a więc:Czy mogę zmusić klasę wykonawczą do zwrócenia obiektu własnego typu?

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

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

mogę zmusić klasę wykonawczą, aby powrócić do obiektu własnego rodzaju? Jeśli to możliwe, to jak? Czy też generics to odpowiedź tutaj?

UWAGA: Kod jest tylko ilustracją, a nie coś, co powinien uruchomić.

+0

Jesteś bardzo ciekawy: dlaczego próbujesz to zrobić? Ogólnie rzecz biorąc, definiowanie interfejsu polega na tym, że kod klienta może ufać, że określony interfejs API jest zdefiniowany w obiekcie, nie wiedząc ani nie dbając o konkretny typ tego obiektu. To jedna z największych zalet OOP. Co to jest, co próbujesz osiągnąć, robiąc to? –

+0

Pomyślałem, że dzięki temu interfejsowi zawsze można ufać, że klasy implementujące interfejs będą miały tę metodę i że zawsze zwrócą swój własny typ. Ale jak mówisz, nie jest to najlepszy projekt OO i zamierzam go porzucić dla metody, która zwraca zamiast tego typ interfejsu. – Cros

Odpowiedz

8

Generics jest odpowiedzią tutaj.

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

Dobra robota ... Właśnie testowałem kod dla tego samego. +1 – jheddings

+0

Natychmiast to spróbuję. – Cros

+0

Wygląda na to, że podczas generowania interfejsu w ten sposób musisz podać T wszędzie, gdzie używasz interfejsu ISelection jako specyfikatora używanego typu, np. Nie mogę teraz zrobić tylko Listy , ale teraz musi to być Lista >. Mam rację? To nie jest rozwiązanie, którego szukam, niestety. – Cros

1

Tak, i to jest znane jako the factory pattern, tylko że zwykle to jest uzupełniane z wykorzystaniem prywatnego konstruktora i uczynienie instancji powrocie metody statyczne, na przykład:

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

Myślę, że kluczem jest wyrażenie "... wymuszenie na klasie implementującej zwracanie obiektu własnego typu ..." –

+0

To naprawdę nie było pytanie "tak/nie". Chcę konkretnie wiedzieć, jak to zrobić w języku C#, jeśli jest to możliwe. – Cros

0

Możesz to zrobić z Generics, ale prawdopodobnie pozostanę przy zwracaniu instancji interfejsu. Zauważ, że skoro klasa implementuje interfejs, zwrócenie jej jest w porządku - będzie to również instancja tego typu i interfejsu.

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

Brak w deklaracji interfejsu, nie. Najlepszym można zarządzać to z rodzajowych:

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

To nie siła realizacja powrót swój własny rodzaj, ale przynajmniej pozwala to zrobić. Dlatego interfejs IClonable zwraca obiekt ze swojej metody Clone, a nie określonego typu.

---- Edit ----

Coś zapamiętać na to pytanie: powiedzmy, że mój kod, dla których nie ma żadnej wiedzy o realizacji, zwraca IParser i kod wywołuje metodę Parse. Jakiego obiektu oczekujesz, aby zostać zwrócony, nie znając konkretnego typu zwróconego odniesienia? Myślę, że próbujesz użyć interfejsów do czegoś, czego nie mają zrobić ...

+1

+1 za wymienienie tej techniki nie wymusza wymaganej implementacji. Równie łatwo można zwrócić kolejną implementację IParser . AFAIK nie ma sposobu na wymuszenie tej kontroli na poziomie języka; to jest najbliższa rzecz, jaką do tego dojdziesz. –

Powiązane problemy