This is part of a series on the new features introduced with C# 10.
Prior to C# 10, working with lambda expressions required a bit more code to be written, for example to explicitly define the delegate type such as Action<T> or Func<T>:
Action<string, ConsoleColor> writeWithColor = (string s, ConsoleColor color) =>
{
var originalColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(s);
Console.ForegroundColor = originalColor;
};
Func<string, string> upper = (string s) => s.ToUpperInvariant();
writeWithColor("Hello", ConsoleColor.Cyan);
Console.WriteLine(upper("This should be default color"));
writeWithColor("Bye", ConsoleColor.Yellow);
Console.ReadLine();
Notice in the preceding code the lambda statement writeWithColor and the lambda expression upper both need explicit delegate types: Action<string, ConsoleColor> and Func<string, string>
From C# 10 we can make use of the new feature of “natural” lambda expression types.
This “natural type” is inferred by the compiler when it can, this means in C# we could just use var: var writeWithColor = (string s, ConsoleColor color) => etc. and var upper = (string s) => s.ToUpperInvariant();
This natural type inference will not always be possible, for example when you haven’t defined lambda parameter types like: var upper = (s) => s.ToUpperInvariant(); If you tried to compile this line of code you would get: Error CS8917 The delegate type could not be inferred.
From C# 10, you can specify an explicit return type for a lambda expression where the compiler can’t work it out for you. You add the return type before the lambda parenthesis:
//Error CS8917 The delegate type could not be inferred
var createException = (bool b) => b ? new ArgumentNullException() : new DivideByZeroException();
// No error
var createException = Exception (bool b) => b ? new ArgumentNullException() : new DivideByZeroException();
You can also sometimes benefit from natural types for method groups:
// C#9
Func getUserInput = Console.ReadLine;
Action tellUser = (string s) => Console.WriteLine(s);
Func waitForEnter = Console.ReadLine;
tellUser("Please enter name");
var name = getUserInput();
tellUser($"Your name is {name}");
waitForEnter();
From C# 10 we could just use var:
// C#10
var getUserInput = Console.ReadLine;
var tellUser = (string s) => Console.WriteLine(s);
var waitForEnter = Console.ReadLine;
tellUser("Please enter name");
var name = getUserInput();
tellUser($"Your name is {name}");
waitForEnter();
You can’t however write: var write = Console.Write; because the Write method has multiple overloads so the compiler doesn’t know which one to choose.
SHARE: