Errori e avvisi quando si usano espressioni lambda e funzioni anonime

Esistono diversi errori correlati alla dichiarazione e all'uso di espressioni lambda:

  • CS0748: utilizzo non coerente dei parametri lambda: i parametri devono essere tutti di tipo esplicito o implicito.
  • CS1621: impossibile utilizzare l'istruzione yield all'interno di un metodo anonimo o di un'espressione lambda.
  • CS1628: non è possibile usare inref o il parametro out all'interno di un metodo anonimo, un'espressione lambda o un'espressione di query.
  • CS1632: il controllo non può lasciare il corpo di un metodo anonimo o di un'espressione lambda.
  • CS1673: i metodi anonimi, le espressioni lambda e le espressioni di query all'interno delle strutture non possono accedere ai membri di istanza di 'this'.
  • CS1686: non è possibile accettare e usare gli indirizzi dell'elemento 'variable' locale o dei rispettivi membri all'interno di un metodo anonimo o di un'espressione lambda.
  • CS1706: l'espressione non può contenere metodi anonimi o espressioni lambda.
  • CS8030: la funzione anonima convertita in un delegato che restituisce un valore nullo non può restituire un valore.
  • CS8175: non è possibile usare la variabile locale ref in un metodo anonimo, in un'espressione lambda o in un'espressione di query.
  • CS8916: gli attributi nelle espressioni lambda richiedono un elenco di parametri tra parentesi.
  • CS8971: interpolatedStringHandlerArgument non ha alcun effetto se viene applicato ai parametri lambda e verrà ignorato nel sito di chiamata.
  • CS8975: la parola chiave var contestuale non può essere usata come tipo restituito lambda esplicito.
  • CS9098: parametro lambda tipizzato in modo implicito '...' non può avere un valore predefinito.

Sono inoltre disponibili diversi avvisi correlati alla dichiarazione e all'uso di espressioni lambda:

  • CS8971: interpolatedStringHandlerArgument non ha alcun effetto se viene applicato ai parametri lambda e verrà ignorato nel sito di chiamata.
  • CS9099: il valore del parametro predefinito non corrisponde al tipo delegato di destinazione.
  • CS9100: il parametro contiene un modificatore di parametri in lambda ma non nel tipo delegato di destinazione.

Limitazioni della sintassi nelle espressioni lambda

Alcune sintassi C# non sono consentite nelle espressioni lambda e nei metodi anonimi. L'uso di costrutti non validi in un'espressione lambda causa gli errori seguenti:

  • CS1621: impossibile utilizzare l'istruzioneyield yield all'interno di un metodo anonimo o di un'espressione lambda.
  • CS1628: Non è possibile usare il parametro in, ref, o out all'interno di un metodo anonimo, un'espressione lambda o un'espressione di query.
  • CS1632: il controllo non può lasciare il corpo di un metodo anonimo o di un'espressione lambda.
  • CS1673: i metodi anonimi, le espressioni lambda e le espressioni di query all'interno delle strutture non possono accedere ai membri di istanza di this.
  • CS1686: non è possibile accettare e usare gli indirizzi dell'elemento 'variable' locale o dei rispettivi membri all'interno di un metodo anonimo o di un'espressione lambda.
  • CS8175: non è possibile usare la variabile locale ref in un metodo anonimo, in un'espressione lambda o in un'espressione di query.

Tutti i costrutti seguenti non sono consentiti nelle espressioni lambda:

  • istruzioniyield (yield return o yield break)
  • Chiamata di un metodo con un parametro in, refo out
  • ref variabili locali
  • istruzionibreak, gotoe continue
  • this accesso quando this è un tipo struct
  • Metodi anonimi o espressioni lambda all'interno di un'altra espressione, ad esempio un costruttore Attribute.

Non è possibile usare nessuno di questi costrutti in un'espressione lambda o in un metodo anonimo. Molti sono consentiti in una funzione locale.

Inoltre, i tipi di gestore di stringhe interpolati vengono ignorati quando vengono applicati a un parametro lambda. Se se ne usa uno, viene visualizzato l'avviso seguente:

  • CS8971: interpolatedStringHandlerArgument non ha alcun effetto se viene applicato ai parametri lambda e verrà ignorato nel sito di chiamata.

Parametri e ritorni dell'espressione lambda

Questi errori indicano un problema con una dichiarazione di parametro:

  • CS0748: utilizzo non coerente dei parametri lambda: i parametri devono essere tutti di tipo esplicito o implicito.
  • CS9098: parametro lambda tipizzato in modo implicito '...' non può avere un valore predefinito.
  • CS8030: la funzione anonima convertita in un delegato che restituisce un valore nullo non può restituire un valore.
  • CS8916: gli attributi nelle espressioni lambda richiedono un elenco di parametri tra parentesi.
  • CS8975: la parola chiave 'var' contestuale non può essere usata come tipo restituito lambda esplicito.

I parametri dell'espressione lambda devono seguire queste regole:

  • Quando un'espressione lambda ha più parametri, tutti i parametri devono essere tipizzati in modo esplicito o tutti i parametri devono essere tipizzati in modo implicito.
  • Tutti i parametri lambda con un valore predefinito devono essere tipizzati in modo esplicito.
  • Se gli attributi vengono applicati a qualsiasi parametro, l'elenco dei parametri deve essere racchiuso tra parentesi.

I tipi restituiti di espressione lambda devono seguire queste regole:

  • Un'espressione lambda che restituisce qualsiasi valore non può essere convertita in un void delegato che restituisce, ad esempio Action.
  • Il tipo restituito è dedotto o un tipo esplicito. Un tipo restituito dichiarato usando la parola chiave var non è consentito.

Tipo delegato espressione lambda

  • CS9099: avviso: il valore del parametro predefinito non corrisponde al tipo delegato di destinazione.

Quando si dichiara un valore predefinito o si aggiunge il modificatore params con un parametro di espressione lambda, il tipo delegato non è uno dei tipi Func o Action. Si tratta invece di un tipo personalizzato che include il valore del parametro predefinito o il modificatore params. Il codice seguente genera avvisi perché assegna un'espressione lambda con un parametro predefinito a un tipoAction:

Action<int> a1 = (int i = 2) => { };
Action<string[]> a3 = (params string[] s) => { };

Per correggere l'errore, rimuovere il parametro predefinito o usare una variabile tipizzata in modo implicito per il tipo delegato:

Action<int> a1 = (int i) => { };
var a2 = (int i = 2) => { };
Action<string[]> a3 = (string[] s) => { };
var a4 = (params string[] s) => { };