2010-10-21 7 views
7

Wenn ich versuche, zwei Überladungen einer Methode zu schreiben, eine akzeptiert einen Expression<Func<T>> Parameter und eine andere akzeptiert eine Func<T>, bekomme ich einen Compilerfehler beim Versuch, die Methode mit einem Lambda-Ausdruck aufzurufen, weil die beiden Signaturen Ambiguität erstellen. Folgendes wäre beispielsweise problematisch:Kann ich eine Methode definieren, um entweder einen Func <T> ODER einen Ausdruck <Func<T>> zu akzeptieren?

Method(() => "Hello"); // Is that a Func<string>, 
         // or is it an Expression<Func<string>>? 

ich bekomme das. Aber ich mag den Ansatz nicht, nur eine Expression<Func<string>> zu akzeptieren, da dies den Aufruf von Code zur Verwendung eines Lambda-Ausdrucks erzwingt. Was, wenn ich auch eine Methodengruppe akzeptieren möchte?

Meine Grundlage diese Frage zu fragen, ist, dass ich auf einigen Code bin zu arbeiten, wo ich möchte in der Lage sein, so etwas zu schreiben:

Method(() => "Hello"); 

... und Ausgabe wie folgt erhalten:

Executed '() => "Hello"' and got "Hello" back.

Inzwischen ich möchte in der Lage sein, dies zu tun, wie gut:

Method(ReturnHello); 

... und Ausgabe wie folgt erhalten:

Executed 'ReturnHello' and got "Hello" back.

Gibt es eine Möglichkeit zu tun, was ich versuche, hier zu tun, ohne nur zwei verschiedene Verfahren Namen (zum Beispiel ExpressionMethod und FuncMethod)? Ich verstehe, dass das nicht so eine große Sache wäre; Ich bin nur neugierig, ob es einen anderen Weg gibt.

+1

Warum verwendet der Titel VB-Syntax und der Rest der Frage mit C# -Syntax? –

+0

Ich denke, Sie müssten Reflektion verwenden, um festzustellen, ob der übergebene Delegat ein Lambda-Ausdruck oder eine Funktion ist. Aber ich denke, jeder Code, den Sie schreiben, sollte das Verhalten zwischen den beiden nicht ändern; das scheint mir ein böser Code-Geruch zu sein. – Reinderien

+0

@klausbyskov: Ich ... weiß es nicht. Ich werde es ändern. –

Antwort

1

Sie können eine Methode überlasten, um entweder eine Func<T> oder Expression<Func<T>> zu nehmen, aber wenn Sie das tun, schlägt die automatische Typbestimmung fehl, also müssen Sie die Typen explizit über Casting definieren. Gefällt mir:

public static void Test() 
{ 
    Test((Func<string>)(() => "helllo")); 
    Test((Expression<Func<string>>) (() => "hello")); 
} 

public static void Test<T>(Func<T> func) 
{ 

} 

public static void Test<T>(Expression<Func<T>> expression) 
{ 

} 

Es ist nicht schön.

+0

Gah, yeah ... Daran habe ich selbst gedacht. Du hast * richtig *, aber ... ich hasse es! –

1

Vielleicht machen Sie eine Methode mit zwei benannten Parametern mit Standardwerten von Null.

Ich weiß, Sie vermissen die OR in diesem, aber das ist einfach in der Methode zu überprüfen.

+1

Whoa ... haha, seltsame Idee. Interessant, zumindest;) –

Verwandte Themen