Lambda expressions with parameter modifiers (ref, out, in, scoped, ref readonly) required explicit type declarations, even when the type could be inferred from context. This made lambdas with modifiers more verbose than necessary.
C# 14.0 allows parameter modifiers to be used without explicit types when the type can be inferred, making modifier-based lambdas as concise as regular lambdas.
Code
csharp
// Modifiers without explicit types
TryParse tryParse = (s, out value) => int.TryParse(s, out value);
RefTransform doubler = (ref x) => { x *= 2; return x; };
SpanLength length = (scoped span) => span.Length;
delegate bool TryParse(string s, out int value);
delegate int RefTransform(ref int value);
delegate int SpanLength(scoped ReadOnlySpan<int> span);csharp
// Modifiers required explicit types
TryParse tryParse = (string s, out int value) => int.TryParse(s, out value);
RefTransform doubler = (ref int x) => { x *= 2; return x; };
SpanLength length = (scoped ReadOnlySpan<int> span) => span.Length;
delegate bool TryParse(string s, out int value);
delegate int RefTransform(ref int value);
delegate int SpanLength(scoped ReadOnlySpan<int> span);Notes
- The compiler infers parameter types from the target delegate type, just like regular lambdas
- Works with
ref,out,in,scoped, andref readonlymodifiers paramsstill requires an explicitly typed parameter list- Parentheses are always required when a modifier is used, even for a single parameter:
(ref x) => ..., notref x => ... - Cannot mix explicitly typed and implicitly typed parameters in the same lambda