59

In C#, is there a way to set a variable from a switch expression? For example:

var a = switch(b)
{
    case c:
    d;

    case e:
    f;

    default:
    g;
};

Is it possible in any other language?

Trevor.Screws
  • 541
  • 6
  • 18
vbullinger
  • 4,016
  • 3
  • 27
  • 32

9 Answers9

124

From C# 8 onwards:

Yes, switch expressions were introduced in C# 8. In terms of syntax, the example would be:

var a = b switch
{
    c => d,
    e => f,
    _ => g
};

... where c and e would have to be valid patterns to match against b. _ represents the default case.

Before C# 8:

No, switch is a statement rather than an expression which can be evaluated.

Of course, you can extract it into another method:

int x = DoSwitch(y);

...

private int DoSwitch(int y)
{
    switch (y)
    {
        case 0: return 10;
        case 1: return 20;
        default: return 5;
    }
}

Alternatively, you could use a Dictionary if it's just a case of simple, constant mappings. If you can give us more information about what you're trying to achieve, we can probably help you work out the most idiomatic way of getting there.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Nope, I can certainly figure it out in a million ways, I just had the a = whatever in each statement and thought I had seen this happen. Guess not. Oh, well. No big deal. – vbullinger Nov 16 '11 at 17:45
  • It is possible now to set a variable to a switch result since c# 8.0. See https://stackoverflow.com/a/58720083/1185067 for example. – Vladislav Stelmakh Nov 27 '19 at 15:00
  • 2
    @VladislavStelmakh: Yes, this is one of the downsides of having written nearly 35,000 answers - I can't go through and update them all every time new features come out... – Jon Skeet Nov 27 '19 at 15:06
  • Any way to utilize switch expressions without returning a value? In my case, I wanted to switch on file extensions that call a particular method that returns void. – ScubaSteve Dec 05 '19 at 17:06
  • @ScubaSteve: No, just use a switch statement in that case. – Jon Skeet Dec 05 '19 at 17:15
  • I like to think that the C# team saw this question and said "that's an awesome idea: we should do that!" – vbullinger Dec 13 '20 at 07:58
  • @AlexfromJitbit: That's a pretty serious accusation. While obviously this was now over 2 years ago, I doubt that I copied and pasted anyone's answer. Yes, Vladislav reminded my of this Q&A in a comment, I see no evidence that I copied and pasted their answer - I really wouldn't have to, given how utterly trivial it is to convert the switch statement in the question into a switch expression. Note that Vladislav's own answer claims that `c` and `e` "should be constants", my own answer indicates that they need to be valid *patterns* (not necessarily constants). – Jon Skeet Dec 23 '21 at 20:25
  • @JonSkeet I deleted my previous comment and I do owe you an apology. I was reviewing the edit history, and for some reason I was under the impression you edited someone else's answer. While you were in fact, editing your own. Gee, apologies for that. Sorry. My initial comment is completely irrelevant. Apologies again – Alex from Jitbit Dec 23 '21 at 20:40
17

No, you can't use a switch statement as an expression. Another way to write it is nested conditional operators:

var a = b == c ? d:
        b == e ? f:
                 g;
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
6

I just wanted to add that Jon Skeet's answer here will not compile and result in an error, since the C#8 switch assignment needs to be closed off with a semicolon.

var a = b switch
{
    c => d,
    e => f,
    _ => g
}; //<-- here

/I am lacking the reputation to comment this under his answer, but since his is the top answer, it should be noted./

I edited the answer in question now

AbandonedCrypt
  • 187
  • 1
  • 12
6

This is not possible in C#.

The closest would be to either move this into a method, or do the assignment in each case individual, ie:

int a;
switch(b)
{
 case c:
     a = d; break;
 case e:
     a = f; break;
 default:
     a = g; break;
};

Is it possible in any other language?

Yes. For example, most functional languages support something similar. For example, F#'s pattern matching provides a (much more powerful) version of this.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
6

If you weren't especially concerned about efficiency, it would be pretty easy to cook up a little class using generics that allowed you to use a "fluent" chain of method calls such as this:

var a=Switch(b).Case(c).Then(d).Case(e).Then(f).Default(g);

or, if you prefer, the more compact

var a=Switch(b).Case(c, d).Case(e, f).Default(g);

If this interests you, I'd be happy to cook up an example

Corey Kosak
  • 2,615
  • 17
  • 13
  • 1
    Wow, this is exactly what I did [here](http://stackoverflow.com/questions/3334138/combine-return-and-switch/3334876#3334876) – Jordão Nov 16 '11 at 17:30
  • 1
    ...though I do think your implementation can be simplified... you can do it with immutable data structures, and there's no need to maintain a dictionary. I might comment on that other thread if you don't mind :-) – Corey Kosak Nov 16 '11 at 17:59
  • Can I accept multiple answers? This one is awesome enough to count, IMHO. – vbullinger Jun 21 '12 at 22:10
4

switch in C# is a statement that doesn't have a "return" value. If you're interested in having a "switch" expression, you can find the little fluent class that I wrote here in order to have code like this:

a = Switch.On(b)
  .Case(c).Then(d)
  .Case(e).Then(f)
  .Default(g);

You could go one step further and generalize this even more with function parameters to the Then methods.

Community
  • 1
  • 1
Jordão
  • 55,340
  • 13
  • 112
  • 144
2

You can do it since c# 8.0, it is called "Switch expressions":

const int c = 1;
int d = 2;
const int e = 3;
int f = 4;
int g = 5;

int b = 3;

var a = b switch
{
    c => d,
    e => f,
    _ => g,
};

Console.WriteLine(a);

a will contain value 4

c and e should be constants as per switch syntax, _ corresponds to the default switch branch

  • I like to think that Microsoft found my post and thought "this is a good idea" and implemented it :) – vbullinger Jan 28 '20 at 20:01
  • This is true, but switching from c#7 to c#8 will introduce nullable reference types, and it's a breaking change for existing code bases, so beware ! – d sharpe Apr 23 '20 at 21:46
  • @dsharpe, nullable reference types are an opt-in feature and should be explicitly configured using tag in csproj or compiler directives such as #nullable enable / #nullable restore – Vladislav Stelmakh Nov 23 '20 at 13:46
1

I wanted the same thing because I use Ruby quite a lot, and that allows you to do that kind of thing. So I created a nuget package called FluentSwitch.

mrstebo
  • 911
  • 9
  • 12
1

No.

A switch statement provides branching control. It is not a function that evaluates to something that could be assigned to a variable.

Eric J.
  • 147,927
  • 63
  • 340
  • 553