📜 ⬆️ ⬇️

New features of C # 8: switch expressions

In late January, the .NET Core development team released a new version of the .NET Core 3 preview 2 framework. It introduced some new features of the C # language. What seems to me quite interesting is the switch expressions. Although this addition seems simple, I think its potential is quite large. Using the new postfix switch construct, you can optionally replace all other branch constructions: if, switch, and the ternary operator. And, which is especially interesting, to make it in a functional style. How exactly, you will learn by reading the article to the end.




switch expression seems pretty simple and intuitive. I think that a small example may be quite enough for review:

// Этот код помещает в переменную result вычисленное значение. // В зависимости от значения переменной operation, будет // выполнено либо сложение, либо вычитание, либо деление. var result = operation switch { "+" => a + b, "-" => a - b, "/" => a / b }; 

The first difference with the switch statement is, of course, the absence of the case and break (or return) keywords. The second, not so obvious, is that the expression after the arrow (=>) must be a calculated expression. As the right side of the assignment operator.

If you know the switch structure well, then you may ask how to define a default? Here it should be noted that starting with C # 7 in switch, you can use pattern matching (pattern matching). Therefore, instead of a special default block, a template is used, the comparison with which is always calculated to be true for any value. This is just an underscore: _.

  // Этот код помещает в переменную result вычисленное значение. // В зависимости от значения переменной operation, будет // выполнено либо сложение, либо вычитание, либо деление. // В случае неподдерживаемой операции будет брошено исключение. var result = operation switch { "+" => a + b, "-" => a - b, "/" => a / b, _ => throw new NotSupportedException() }; 

Since the pattern matching is performed in turn, you should not put such a construction first. No other comparisons will be made.

But there is one thing
In fact, the compiler will not let you do this. The error will be something like this: error CS8510: The pattern has already been handled.

Another unobvious feature of the switch expression is that all expressions must return the same type. For example, only int. Or just string. In this switch expression is similar to the ternary operator.

The only question that remains is how to perform several operations in the expression? There is no beautiful solution yet, but the use of lambda functions is closest to the ideal.

  // Этот код помещает в переменную result вычисленное значение. // В зависимости от значения переменной operation, будет // выполнено либо сложение, либо вычитание, либо деление. // В случае неподдерживаемой операции будет брошено исключение. // Все поддерживаемые операции логируются. var result = operation switch { "+" => ((Func<int>)(() => { Log("сложение"); return a + b; }))(), "-" => ((Func<int>)(() => { Log("вычитание"); return a - b; }))(), "/" => ((Func<int>)(() => { Log("деление"); return a / b; }))(), _ => throw new NotSupportedException() }; 

Why do I think this change is potentially significant?

Let's see how a switch expression replaces other language constructs. Let there be the following if:

 var error = ""; if (fileSize > 1000) { error = "file is too large" } else { processFile(); } 

Similar code using switch expression:

 var error = (fileSize > 1000) switch { true => "file is too large", _ => ((Func<string>)(() => { processFile(); return ""; }))() }; 

Since switch is relatively easy to translate into a set of if -s, replacing any switch is also not difficult. The ternary operator is also trivially replaced.

Naturally, the solution with the explicit use of Func <> is not beautiful. But if this technical problem is solved, the switch expression will be much more convenient and, in many cases, preferable.

If you are interested in the possibilities of C # 8, then you may be interested in screencasts on nullable reference types and using declaration, which can be found on my youtube channel .

About the author: Alexander Netkachev graduated from Tavrichesky National University with a degree in Computer Science. Works and lives in the UK. For many years he has been engaged in professional software development, he maintains a personal site [there was a link to the author’s site, but since TM believes that having a paid udemy course and mentioning it on the author’s site is a paid service, it is removed].

Source: https://habr.com/ru/post/440254/