Condividi tramite


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 di parametri lambda incoerenti. I tipi di parametro devono essere tutti espliciti o tutti impliciti.
  • CS1621: l'istruzione yield non può essere usata all'interno di un metodo anonimo o di un'espressione lambda.
  • CS1628: impossibile usare inref o out parametri 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: metodi anonimi, espressioni lambda ed espressioni di query all'interno di struct non possono accedere ai membri dell'istanza di "this".
  • CS1686: variabile locale o i relativi membri non possono avere l'indirizzo preso e essere usati 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 void non può restituire un valore.
  • CS8175: impossibile usare ref local all'interno di un metodo anonimo, un'espressione lambda o un'espressione di query.
  • CS8916: gli attributi nelle espressioni lambda richiedono un elenco di parametri racchiusi tra parentesi.
  • CS8971: InterpolatedStringHandlerArgument non ha alcun effetto se applicato ai parametri lambda e verrà ignorato nel sito di chiamata.
  • CS8975: la parola chiave var contestuale non può essere usata come tipo di ritorno esplicito della lambda.
  • 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 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 ha modificatore params in lambda ma non nel tipo delegato di destinazione.

Il compilatore genera anche il messaggio informativo seguente:

  • CS9236: La compilazione richiede di legare l'espressione lambda almeno un certo numero di volte. Valuta la possibilità di dichiarare l'espressione lambda con tipi di parametro espliciti oppure, se la chiamata al metodo contenitore è generica, valuta l'utilizzo di argomenti di tipo esplicito.

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: l'istruzione yield non può essere usata all'interno di un metodo anonimo o di un'espressione lambda.
  • CS1628: non è possibile usare inil parametro , refo out all'interno di un metodo anonimo, un'espressione lambda o un'espressione di query.
  • CS1632: Controllo non può lasciare il corpo di un metodo anonimo o di un'espressione lambda.
  • CS1673: metodi anonimi, espressioni lambda ed espressioni di query all'interno di struct non possono accedere ai membri dell'istanza di this.
  • CS1686: variabile locale o i relativi membri non possono avere l'indirizzo preso e essere usati all'interno di un metodo anonimo o di un'espressione lambda.
  • CS8175: impossibile usare ref local all'interno di un metodo anonimo, un'espressione lambda o un'espressione di query.

Tutti i costrutti seguenti non sono consentiti nelle espressioni lambda:

  • yield istruzioni (yield return o yield break)
  • Chiamare un metodo che ha un parametro in, ref o out
  • ref variabili locali
  • istruzionibreak, gotoe continue
  • this accesso quando this è di 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 si usa uno, viene visualizzato l'avviso seguente:

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

Alcune espressioni causano l'emissione dell'avviso informativo seguente da parte del compilatore:

  • CS9236: La compilazione richiede di associare l'espressione lambda per almeno un certo numero di volte. Considerare di dichiarare l'espressione lambda con tipi di parametro espliciti o, se la chiamata al metodo che la contiene è generica, considerare di usare argomenti di tipo esplicito.

La complessità delle espressioni lambda e il modo in cui richiamano altre espressioni lambda influiscono negativamente sulle prestazioni del compilatore. Il motivo è che il compilatore deve dedurre i tipi di parametro e argomento tramite le espressioni lambda e i potenziali tipi richiedono tempo.

Parametri di espressione lambda e restituzioni

Questi errori indicano un problema con una dichiarazione di parametro:

  • CS0748: utilizzo di parametri lambda incoerenti. I tipi di parametro devono essere tutti espliciti o tutti impliciti.
  • CS9098: parametro lambda tipizzato in modo implicito '...' non può avere un valore predefinito.
  • CS8030: la funzione anonima convertita in un delegato che restituisce void non può restituire un valore.
  • CS8916: gli attributi nelle espressioni lambda richiedono un elenco di parametri racchiusi tra parentesi.
  • CS8975: la parola chiave contestuale 'var' 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 tipizzato in modo esplicito o tutti i parametri devono essere tipizzato in modo implicito.
  • Tutti i parametri lambda con un valore predefinito devono essere tipizzato 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 restituito, ad esempio Action.
  • Il tipo restituito è dedotto o un tipo esplicito. Non è consentito dichiarare un tipo di ritorno usando il keyword var.

Tipo di espressione lambda delegato

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

Quando si dichiara un valore predefinito o si aggiunge il params modificatore 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 Action tipo:

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) => { };