2012-09-25 21 views
24

Ich möchte eine generische Typ-Konverter-Funktion an eine Methode senden, aber ich kann nicht herausfinden, wie es geht.Wie kann ich eine Funktion mit einem generischen Typparameter übergeben?

Hier ungültige Syntax, die erklärt, was ich erreichen möge, das Problem, das ich nicht wissen, ist, wie der generischen Typen angeben zusammen mit meiner func:

public void SomeUtility(Func<T><object,T> converter) 
{ 
    var myType = converter<MyType>("foo"); 
} 

bearbeiten (siehe auch meine Diskussion in den Kommentaren mit Lawrence): mit dem „generic Wandler“ ich meinte wurde ich in einem Konverter passieren mag, die einen starken Typen <T> (nicht Objekt) umwandeln können, so in meiner Methode die nächste Zeile sein könnte:

var myOtherType = converter<MyOtherType>("foo"); 

Der Delegierte Ich mag es, p Esel als ein Parameter wie folgt aussehen würde:

private delegate TOutput myConverterDelegate<TOutput>(object objectToConvert); 

Dies ist mehr eine Syntax/C# Exploration nun, Dinge zu erledigen ich wahrscheinlich stattdessen eine Schnittstelle verwenden, aber ich hoffe, dass dies möglich ist, mit einem zu erreichen Funktion/Delegierter.

+0

Ist die Tatsache, dass Sie einen Typ innerhalb des Methodenkörpers angegeben haben, von Bedeutung? Bedeuten Sie, dass diese Methode möglicherweise Conversions für mehrere Typen vornehmen muss und nicht für einen bestimmten Typ, der vom Aufrufer definiert wird? –

+0

Ja, das habe ich versucht, als "generischen Typkonverter" auszudrücken, also könnte die nächste Zeile var sein myOtherType = converter ("foo"); – joeriks

+0

Ok - dann denke ich, dass du meine Antwort nützlich finden wirst :) –

Antwort

19

Sie können keine Instanzen von generischen Funktionen oder Aktionen haben - alle Typparameter im Voraus festgelegt und kann nicht durch den Anrufer neu definiert werden.

Eine einfache Möglichkeit wäre Polymorphismus ganz zu vermeiden, indem sie sich auf Down-Casting:

public void SomeUtility(Func<Type, object, object> converter) 
{ 
    var myType = (MyType)converter(typeof(MyType), "foo"); 
} 

Wenn Sie geben Sicherheit wollen, müssen Sie die Definition der Typparameter an den Aufrufer verschieben. Sie können dies tun, indem Sie eine generische Methode innerhalb einer Schnittstelle zu komponieren:

public void SomeUtility(IConverter converter) 
{ 
    var myType = converter.Convert<MyType>("foo"); 
} 

interface IConverter 
{ 
    T Convert<T>(object obj); 
} 

Edit:

Wenn der ‚Konverter Typ‘ auf dem Call Ort bekannt ist, und nur wird diese Art innen verwendet werden Die Utility-Methode, dann können Sie einen generischen Typ für die Methode definieren und diesen verwenden, genau wie andere Poster vorgeschlagen haben.

+0

Ok danke, ja ich werde wahrscheinlich nur eine Schnittstelle benutzen, danke, dass du mich in diese Richtung gelenkt hast. Aber sollte es aus Interesse nicht möglich sein, dass ein Delegierter/eine Funktion einen generischen Typ weitergibt? Beschrieben als ein Delegat Ich denke, ich würde es als schreiben: private Delegate TOutput myConverterDelegate (object objectToConvert); - aber wenn ich versuche, das als Parameter zu verwenden, bekomme ich "benötigt 1 Typ Argumente" – joeriks

+1

Sie können * generische Delegierte sicherlich * definieren, schließlich ist das genau das, was Func und Action sind. Sie werden als * generische Definitionen * behandelt, genau wie generische Interfaces und Klassen. Sie können jedoch * generische Definitionen * in Methodensignaturen nicht verwenden, nur parametrisierte * generische Typen *. Sie können einfach nicht das tun, was Sie mit einem Delegierten allein erreichen wollen. –

7

Sie müssen auch SomeUtility generisch machen. Dadurch und die Syntax Festsetzung gibt:

public void SomeUtility<T>(Func<object,T> converter) 
{ 
    var myType = converter("foo"); 
} 
15
public void SomeUtility<T>(Func<object, T> converter) 
{ 
    var myType = converter("foo"); 
} 

und dann:

SomeUtility(arg => new MyType()); 

Der Gattungs Typinferenz wird in diesem Fall arbeiten.

+0

dieser sollte akzeptiert werden –

3

Sie müssen den T-Typ zur Kompilierzeit kennen, um ihn zu verwenden. Das T kann entweder auf Klassenebene oder auf Methodenebene angegeben werden.

class SomeClass<T> { 
    public void SomeUtility(Func<object, T> converter) { 
     var myType = converter("foo"); // Already is the T-type that you specified. 
    } 
} 

oder

public void SomeUtility<T>(Func<object, T> converter) { 
    var myType = converter("foo"); // Already is the T-type that you specified. 
} 
Verwandte Themen