2009-06-25 4 views
2

Ich arbeite durch einen Fehler. Bei der Neuerstellung des Fehlers für das folgende Beispiel konnte ich feststellen, warum das Problem auftritt. Aber ich bin auf der Suche nach einer besseren Lösung. So das folgende Programm gegeben:Wie kann T während der Implementierung einer Schnittstelle korrekt von einer generischen Methode zurückgegeben werden?

bar 
bar 

Aber was ich bin immer ist: wie diese vereinfachte

foo 
bar 

sehen das Problem ist es

public interface IFoo<T> { 
    T OutputType(T param); 
} 

class Foo : IFoo<Foo> { 
    public virtual Foo OutputType(Foo param) { 
     Console.WriteLine("foo"); 
     return param; 
    } 
} 

class Bar : Foo, IFoo<Bar> { 
    public virtual Bar OutputType(Bar param) { 
     Console.WriteLine("bar"); 
     return param;  
    } 
} 

class Program { 
    static void Main(string[] args) { 
     Bar bar = new Bar(); 
     CallOutputType(bar); 
     bar.OutputType(bar); 
    } 

    static void CallOutputType<T>(T t) where T : Foo { 
     t.OutputType(t); 
    }  
} 

ich die Ausgabe zu sein, erwartete offensichtlich, dass Bar.OutputType nicht überschreibt Foo.OutputType. Was sind meine besten Möglichkeiten, dieses Design zu verbessern? Bar.OutputType kann nicht überschrieben werden Foo.OutputType, weil die Signaturen unterschiedlich sind. Ändern der Signatur von Bar.OutputType passen Foo.OutputType wird nicht funktionieren, weil dann Bar nicht IFoo werden implimenting.

Antwort

5

Uh, ich bin nicht allzu vertraut mit diesem Zeug, aber es sollte nicht sein:

static void CallOutputType<T>(T t) where T : IFoo<T> 
{ 
    t.OutputType(t); 
} 

Es funktionierte, als ich es kompiliert.

+0

Hmm, ich versuche, dies jetzt zu testen, was ich glaube, ich könnte Am Ende ist das in CallOutputType - ((IFoo ) t) .OutputType (t); Ich kann die Methodenkonstante aus anderen Gründen nicht ändern. – Bob

+0

Vielen Dank, dass Sie mich in die richtige Richtung weisen, indem Sie die Schnittstelle verwenden, um die Methode aufzurufen. – Bob

0

Wie wäre dies der Bar-Klasse hinzu:

public override Foo OutputType(Foo param) 
    { 
     return this.OutputType((Bar)param); 
    } 
0

Wie wäre Ihre Interface-Definition konvertieren, so dass param ‚s Typ IFoo zu verlängern erklärt wird?

0

Ich würde Spencer zweitens - wenn Sie generische Constraint ist T: Foo, es Typcasts Ihre Bar in ein Foo, und natürlich Sie die OutputType-Methode der Foo-Klasse dann aufrufen.

0

Ich bin mir nicht sicher, was Sie am Ende erreichen wollen, aber würde das helfen?

Wenn Sie eine generische hinzuzufügen, was jemals implementiert IFoo dann können Sie den Typ angeben, wenn das abgeleitete Objekt erstellt wird ...

public class Foo<TFoo> : IFoo<TFoo> 
{ 

} 

//Then you code would allow this... 
//Again other then returning Bar both times I am not certain exactly what you are 
//wanting to accomplish But specifying the type at create will allow you to return Bar 
//even if you created a Foo or a Bar... 

class Program { 
    static void Main(string[] args) { 
     Foo foo = new Foo<Bar>(); 
     CallOutputType(foo); 
     foo.OutputType(foo); 
    } 

    static void CallOutputType<T>(T t) where T : Foo { 
     t.OutputType(t); 
    }  
} 
Verwandte Themen