2013-01-10 14 views
20

C'è un modo per utilizzare optional arguments (parametri predefiniti) con lambda expressions in C#? Ho letto la documentazione ma non riesco a trovare nulla da dire in un modo o nell'altro.È possibile utilizzare i parametri opzionali/predefiniti in un'espressione lambda in C#?

Per illustrare, posso definire semplice metodo che utilizza un argomento opzionale per fornire un valore di default in questo modo:

void MyMethod(string arg = "default-value") 
{ 
    Console.WriteLine(arg); 
} 

Quello che voglio sapere è se sono in grado di fare la stessa cosa con un lambda espressione.

// gives a syntax error 
Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg); 

posso lavorare in un parametro facoltativo con un valore predefinito utilizzando un delegato, ma questo sembra un po 'goffo.

delegate void MyDelegate(string arg = "default"); 
MyDelegate MyMethod = arg => Console.WriteLine(arg); 

In alternativa ho potuto verificare il parametro nel corpo lambda, qualcosa di simile ...

Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ? 
            "default" : 
            arg); 

Ma ancora una volta questo sembra un po 'goffo.

È possibile utilizzare i parametri facoltativi per impostare un valore predefinito in un'espressione lambda in C#?

+0

possibile duplicato di [Come passare un metodo con parametri facoltativi come argomento?] (Http://stackoverflow.com/questions/12728844/how-to-pass-a-method-with-optional-parameters-as -an-argomento) – horgh

+0

Questo non ha senso. Non si può chiamare comunque "Azione " senza argomento. – SLaks

+1

@KonstantinVasilcov - non è affatto un duplicato - sto specificatamente chiedendo espressioni lambda - non semplici metodi. Pensavo di averlo chiarito, scusa. – Fraser

risposta

21

No. Il chiamante (il codice che richiama il delegato) non "vede" l'espressione lambda, quindi non ha senso specificare il parametro predefinito lì. Tutto il chiamante vede è il delegato. Nel tuo caso, ad esempio, il codice di chiamata solo sa di Action<string> - come intende il compilatore sapere di fornire il valore predefinito specificato dall'espressione lambda?

Come esempio di come le cose si complicano, immaginate se questo fosse valido. Quindi prendere in considerazione questo codice:

Action<string> action; 
if (DateTime.Today.Day > 10) 
{ 
    action = (string arg = "boo") => Console.WriteLine(arg); 
} 
else 
{ 
    action = (string arg = "hiss") => Console.WriteLine(arg); 
} 
action(); // What would the compiler do here? 

Tenete a mente che l'argomento è fornito dal compilatore presso il sito chiamata - così che cosa dovrebbe fare con la linea finale?

È un po 'come avere un'interfaccia e un'implementazione - se si dispone di un parametro predefinito su un'interfaccia, va bene; se lo si ha solo sull'implementazione, solo i chiamanti che conoscono l'implementazione specifica lo vedranno. Nel caso delle espressioni lambda, non c'è davvero alcuna implementazione visibile da usare per il chiamante: c'è solo la firma del delegato.

+0

+1 Grazie, ha senso. Stavo solo provando qualcosa e all'inizio sembrava che dovesse funzionare ... – Fraser

2

Il lambda corrisponderà a qualsiasi firma del delegato a cui è assegnato; senza essere assegnato a un delegato non è possibile compilare un lambda.

Se il delegato contiene argomenti facoltativi, l'utilizzo di tale delegato può facoltativamente fornire argomenti. Se il delegato non lo fa, l'uso di tale delegato non può omettere alcun argomento.

Mentre i delegati Action e Func sono molto utili e possono rappresentare la maggior parte delle firme, non possono rappresentare alcuna firma con argomenti facoltativi; devi usare un'altra definizione di delegato per questo.

Remeber, Action e Func non sono particolarmente speciali, sono solo due delegati che tutti usano così non devono preoccuparsi di creare il proprio per ogni piccola cosa.

Problemi correlati