Lambda Parameter Modifiers Without Types — Modern C# 14 Syntax

Lambda Parameter Modifiers Without Types — Modern C# 14 Syntax C# 14 brings a new level of flexibility and readability to lambda expressions by allowing parameter modifiers like ref, out, in, and scoped in untyped parameter lists. Previously, to use any modifier, you had to explicitly declare the parameter types. Now, the compiler infers the types while still allowing these powerful modifiers — reducing verbosity in functional programming constructs and delegate definitions. In this post, you’ll learn: What modifiers can be used with lambda parameters What changed in C# 14 Examples with ref, out, and scoped Use cases and best practices What’s New? C# 13 and earlier: Modifiers required full type declarations: TryParse parser = (string text, out int result) => int.TryParse(text, out result); C# 14: Modifiers are allowed with implicitly typed parameters: TryParse parser = (text, out result) => int.TryParse(text, out result); Type inference still happens, but now with modifiers included — giving you flexibility and clarity. Practical Examples ✔️ TryParse Delegate (out modifier) delegate bool TryParse(string text, out T result); // ✅ C# 14 — out modifier without type declaration TryParse parser = (text, out result) => int.TryParse(text, out result); ✔️ In-place ref modifier delegate void Apply(ref int number); // ✅ C# 14 Apply doubleIt = (ref n) => n *= 2; ✔️ In modifier for readonly reference delegate int Square(in int value); // ✅ C# 14 Square square = (in v) => v * v; ✔️ Scoped modifier for local reference enforcement delegate void Capture(scoped ref int x); // ✅ C# 14 Capture keepIt = (scoped ref n) => Console.WriteLine(n); ❌ Still Not Allowed: params modifier in implicit form // ❌ Requires explicit type delegate void Log(params string[] messages); // Must be: Log logger = (string[] args) => Console.WriteLine(string.Join(", ", args)); Why It Matters Feature Benefit Less boilerplate Skip types while keeping powerful syntax Easier to read and write Especially in functional APIs More flexible delegate usage Works with built-in and custom delegates Supports scoped safety patterns Especially for ref struct validation Best Practices Use out and ref modifiers in functional delegates for parsing or transformations. Avoid complex logic in lambdas with multiple modifiers — refactor into methods. Combine with delegates like SpanAction or TryParse for performance-critical tasks. Remember: params still requires explicit typing. Learn More Lambda expressions - C# language reference Delegates and ref parameters in C# Final Thoughts With C# 14, lambdas become cleaner, smarter, and more powerful — especially for developers who rely on high-performance delegates and modern memory-safe APIs. This feature may seem small, but it contributes greatly to a more expressive and modern C#. The future of functional-style programming in .NET just got sharper. Written by: [Cristian Sifuentes] – .NET Functional Enthusiast | C# Power User | Delegate Whisperer Have you used this in production code yet? Share your story!

May 7, 2025 - 01:36
 0
Lambda Parameter Modifiers Without Types — Modern C# 14 Syntax

LambdaParameterModifiersWithoutTypes

Lambda Parameter Modifiers Without Types — Modern C# 14 Syntax

C# 14 brings a new level of flexibility and readability to lambda expressions by allowing parameter modifiers like ref, out, in, and scoped in untyped parameter lists.

Previously, to use any modifier, you had to explicitly declare the parameter types. Now, the compiler infers the types while still allowing these powerful modifiers — reducing verbosity in functional programming constructs and delegate definitions.

In this post, you’ll learn:

  • What modifiers can be used with lambda parameters
  • What changed in C# 14
  • Examples with ref, out, and scoped
  • Use cases and best practices

What’s New?

C# 13 and earlier:

Modifiers required full type declarations:

TryParse<int> parser = (string text, out int result) => int.TryParse(text, out result);

C# 14:

Modifiers are allowed with implicitly typed parameters:

TryParse<int> parser = (text, out result) => int.TryParse(text, out result);

Type inference still happens, but now with modifiers included — giving you flexibility and clarity.

Practical Examples

✔️ TryParse Delegate (out modifier)

delegate bool TryParse<T>(string text, out T result);

// ✅ C# 14 — out modifier without type declaration
TryParse<int> parser = (text, out result) => int.TryParse(text, out result);

✔️ In-place ref modifier

delegate void Apply(ref int number);

// ✅ C# 14
Apply doubleIt = (ref n) => n *= 2;

✔️ In modifier for readonly reference

delegate int Square(in int value);

// ✅ C# 14
Square square = (in v) => v * v;

✔️ Scoped modifier for local reference enforcement

delegate void Capture(scoped ref int x);

// ✅ C# 14
Capture keepIt = (scoped ref n) => Console.WriteLine(n);

❌ Still Not Allowed: params modifier in implicit form

// ❌ Requires explicit type
delegate void Log(params string[] messages);

// Must be:
Log logger = (string[] args) => Console.WriteLine(string.Join(", ", args));

Why It Matters

Feature Benefit
Less boilerplate Skip types while keeping powerful syntax
Easier to read and write Especially in functional APIs
More flexible delegate usage Works with built-in and custom delegates
Supports scoped safety patterns Especially for ref struct validation

Best Practices

  • Use out and ref modifiers in functional delegates for parsing or transformations.
  • Avoid complex logic in lambdas with multiple modifiers — refactor into methods.
  • Combine with delegates like SpanAction or TryParse for performance-critical tasks.
  • Remember: params still requires explicit typing.

Learn More

Final Thoughts

With C# 14, lambdas become cleaner, smarter, and more powerful — especially for developers who rely on high-performance delegates and modern memory-safe APIs.

This feature may seem small, but it contributes greatly to a more expressive and modern C#.

The future of functional-style programming in .NET just got sharper.

Written by: [Cristian Sifuentes] – .NET Functional Enthusiast | C# Power User | Delegate Whisperer

Have you used this in production code yet? Share your story!