Dot Net

Don’t Code Tired | What’s New in C# 10: Easier Lambda Expressions

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>:

// C# 9
Action writeWithColor = (string s, ConsoleColor color) =>
{
    var originalColor = Console.ForegroundColor;
    Console.ForegroundColor = color;
    Console.WriteLine(s);
    Console.ForegroundColor = originalColor;
};

Func 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:









Source link

Related Articles

Back to top button