-1

Can someone explain this error to me, I just don't get how it thinks there's a type involved

var header = "ABCDEfooGHIJ";

switch (true)
{
    case header.Contains("foo"): //error here
        return true;
    case header.Contains("bar"): //and here
        return false; 
}

Error = 'header' is a variable but is used like a type

Jonas W
  • 3,200
  • 1
  • 31
  • 44
  • 12
    This isn't now switch statements work in C#. The thing in the `switch (...)` needs to be a variable you're switching over, and the things in the `case` statement have to be patterns which match that variable. You want an `if / else if` statement – canton7 May 24 '21 at 12:32
  • https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch – aepot May 24 '21 at 12:33
  • 2
    please do not ever use `switch(true)`-style statements. it's an anti-pattern. a chain of `if ... elseif` in this case would be the by far better solution. (personally, i find `switch(true)` to be only marginally less bad than `goto`) – Franz Gleichmann May 24 '21 at 12:34
  • 1
    Alternatively, use a dictionary where the key is a func and the value is a bool (or it could even be done with a hashset). But the `if` is likely simpler. – mjwills May 24 '21 at 12:34
  • 1
    `switch (true)` is never meaningful. – PMF May 24 '21 at 12:34
  • Because you are passing method in switch case, this is not allowed. I don't know if you are necessarily Switch statement , you could do, bool result=header.Contains("foo")?true:false; – zia khan May 24 '21 at 12:35
  • The compiler thinks there should be a type probably because it expects a type pattern (?) – Sweeper May 24 '21 at 12:36
  • 1
    The error is because it's looking for a pattern [including a deconstruction](https://learn.microsoft.com/en-us/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-in-csharp-8-0#expressing-patterns), e.g. `case Point(int x, int y)`. The closest it can get is something like `case ContainingType.Point(int x, int y)`, so it's matching `header` against a type which contains the deconstructable type `Contains`, which is failing. – canton7 May 24 '21 at 12:41
  • I've linked this question to a similar one. While the question is slightly different in the linked question, the answer over there explains *why* you're seeing the compiler error you're seeing (except in your case it's looking for a recursive pattern which has a single constant parameter `"foo"`, rather than one which has no parameters) – canton7 May 24 '21 at 12:54

1 Answers1

4

switch (true) isn't a "thing" in C# like it's VB counterpart (Select True) . And even if it was, I'd strongly recommend avoiding it.

When you write a switch statement in C#, the cases must either be a constant or a pattern match. If you are insistent on using a switch, you can use the following (which only works on C# 7+)

switch (header)
{
   case var _ when header.Contains("foo"):
       return true:
   case var _ when header.Contains("bar"):
       return false:
   default:
       throw new Exception();
}

In this case, var _ is the object pattern (which will match anything non-null) along with a discard since we want to operate on the other variable. Don't like the discard? You could do this as well:

switch (header)
{
   case var h1 when h1.Contains("foo"):
       return true:
   case var h2 when h2.Contains("bar"):
       return false:
   default:
       throw new Exception();
}

That said, don't use a switch for this. A chain of if/else is much more clear. Anyone reading your code (including your future self) will thank you for it.

if (header.Contains("foo"))
    return true;
if (header.Contains("bar"))
   return false;
// etc
pinkfloydx33
  • 11,863
  • 3
  • 46
  • 63