Sdílet prostřednictvím


Chyby a upozornění při použití výrazů lambda a anonymních funkcí

Deklarace a používání výrazů lambda souvisí s několika chybami :

  • CS0748: Nekonzistentní použití parametru lambda; typy parametrů musí být explicitní nebo všechny implicitní.
  • CS1621: Příkaz yield nelze použít uvnitř anonymní metody nebo výrazu lambda.
  • CS1628: Nelze použít parametr inref nebo out uvnitř anonymní metody, lambda výrazu nebo dotazu.
  • CS1632: Kontrola nemůže opustit tělo anonymní metody nebo výrazu lambda.
  • CS1673: Anonymní metody, výrazy lambda a výrazy dotazů uvnitř struktur nemají přístup k členům instance 'this'.
  • CS1686: Místní proměnná nebo její členové nemohou mít svou adresu vzatou a být použity uvnitř anonymní metody nebo lambda výrazu.
  • CS1706: Výraz nemůže obsahovat anonymní metody ani výrazy lambda.
  • CS8030: Anonymní funkce převedená na neplatný delegát nemůže vrátit hodnotu.
  • CS8175: Nelze použít ref local uvnitř anonymní metody, výrazu lambda nebo výrazu dotazu.
  • CS8916: Atributy výrazů lambda vyžadují seznam závorek parametrů.
  • CS8971: InterpolatedStringHandlerArgument nemá žádný vliv při použití na parametry lambda a bude ignorován v lokalitě volání.
  • CS8975: Kontextové klíčové slovo var nelze použít jako explicitní návratový typ lambda.
  • CS9098: Implicitně typovaný parametr lambda '...' nemůže mít výchozí hodnotu.

Kromě toho existuje několik upozornění souvisejících s deklarací a používáním výrazů lambda:

  • CS8971: InterpolatedStringHandlerArgument nemá žádný vliv při použití na parametry lambda a bude ignorován v lokalitě volání.
  • CS9099: Výchozí hodnota parametru se neshoduje s typem cílového delegáta.
  • CS9100: Parametr má modifikátor parametrů v lambda, ale ne v cílovém typu delegáta.

Kompilátor také vytvoří následující informační zprávu:

  • CS9236: Kompilace vyžaduje vazbu lambda výrazu alespoň několikrát. Zvažte deklarování lambda výrazu s explicitními typy parametrů nebo pokud je volání v rámci metody generické, zvažte použití explicitních argumentů typu.

Omezení syntaxe ve výrazech lambda

Některé syntaxe jazyka C# jsou zakázány ve výrazech lambda a anonymních metodách. Použití neplatných konstruktorů ve výrazu lambda způsobuje následující chyby:

  • CS1621: Příkaz yield nelze použít uvnitř anonymní metody nebo výrazu lambda.
  • CS1628: Nelze použít in, refnebo out parametr uvnitř anonymní metody, výrazu lambda nebo výrazu dotazu.
  • CS1632: Ovládací prvek nemůže opustit tělo anonymní metody nebo výraz lambda.
  • CS1673: Anonymní metody, výrazy lambda a výrazy dotazů uvnitř struktur nemohou přistupovat k členům thisinstance .
  • CS1686: Na adresu místní proměnné nebo jejích členů nelze odkazovat a použít ji uvnitř anonymní metody nebo lambda výrazu.
  • CS8175: Nelze použít ref local uvnitř anonymní metody, výrazu lambda nebo výrazu dotazu.

Ve výrazech lambda jsou zakázány všechny následující konstrukty:

  • yield příkazy (yield return nebo yield break)
  • Volání metody, která má inparametr , refnebo out
  • ref místní proměnné
  • break, gotoa continue příkazy
  • this přístup, když this je typu struct
  • Anonymní metody nebo výrazy lambda uvnitř jiného výrazu, například konstruktor Attribute.

Nelze použít žádný z těchto konstrukcí ve výrazu lambda ani v anonymní metodě. Mnoho z nich je povoleno v místní funkci.

Kromě toho se typy interpolovaných zpracovatelů řetězců při použití na parametr lambda ignorují. Pokud ji použijete, zobrazí se následující upozornění:

  • CS8971: InterpolatedStringHandlerArgument nemá žádný vliv při použití na parametry lambda a bude ignorován v lokalitě volání.

Některé výrazy způsobují, že kompilátor vygeneruje následující informační upozornění:

  • CS9236: Kompilace vyžaduje, aby byl výraz lambda svázán alespoň několikrát. Zvažte deklarování výrazu lambda s explicitními typy parametrů, nebo pokud je obalující volání metody generické, zvažte použití explicitních argumentů typu.

Složitost výrazů lambda a jejich vyvolání jiných výrazů lambda má negativní vliv na výkon kompilátoru. Důvodem je, že kompilátor musí odvodit typy parametrů a argumentů prostřednictvím výrazů lambda a potenciální typy, což vyžaduje čas.

Parametry výrazu lambda a návratové hodnoty

Tyto chyby značí problém s deklarací parametru:

  • CS0748: Nekonzistentní použití parametru lambda; typy parametrů musí být explicitní nebo všechny implicitní.
  • CS9098: Implicitně zadaný parametr lambda '...' nemůže mít výchozí hodnotu.
  • CS8030: Anonymní funkce převedená na delegáta vracejícího void nemůže vrátit hodnotu.
  • CS8916: Atributy výrazů lambda vyžadují seznam závorek parametrů.
  • CS8975: Kontextové klíčové slovo var nelze použít jako explicitní návratový typ lambda.

Parametry výrazu lambda musí dodržovat tato pravidla:

  • Pokud má výraz lambda více parametrů, musí být buď zadány všechny parametry explicitně, nebo všechny parametry musí být implicitně zadány.
  • Všechny parametry lambda s výchozí hodnotou musí být explicitně zadány.
  • Pokud jsou atributy použity na jakékoli parametry, seznam parametrů musí být uzavřen v závorkách.

Návratové typy výrazu lambda musí dodržovat tato pravidla:

  • Výraz lambda, který vrací jakoukoli hodnotu, nelze převést na vráceného delegáta void , například Action.
  • Návratový typ je dovozen, nebo je explicitně určený. Návratový typ deklarovaný pomocí klíčového slova var není povolený.

Typ delegáta výrazu lambda

  • CS9099: Upozornění: Výchozí hodnota parametru se neshoduje s typem cílového delegáta.

Když deklarujete výchozí hodnotu nebo přidáte params modifikátor s parametrem výrazu lambda, typ delegáta není jedním z Func nebo Action typů. Jedná se spíše o vlastní typ, který obsahuje výchozí hodnotu parametru nebo params modifikátor. Následující kód generuje upozornění, protože přiřadí výraz lambda, který má výchozí parametr typu Action :

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

Chybu opravíte tak, že odeberete výchozí parametr nebo použijete implicitně za typ delegáta proměnnou:

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