Switch case in C# - a constant value is expected

C#Switch Statement

C# Problem Overview


My code is as follows:

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    switch (dataSourceName)
    {
        case (string)typeof(CustomerDetails).Name.ToString(); :
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}

But this is not working. The case statement is giving me an error saying that a constant variable is expected. Please help guys thank you!

C# Solutions


Solution 1 - C#

See https://stackoverflow.com/questions/44905/c-switch-statement-limitations-why

Basically Switches cannot have evaluated statements in the case statement. They must be statically evaluated.

Solution 2 - C#

You can only match to constants in switch statements.


Example:

switch (variable1)
{
    case 1: // A hard-coded value
        // Code
        break;
    default:
        // Code
        break;
}

Successful!


switch (variable1)
{
    case variable2:
        // Code
        break;
    default:
        // Code
        break;
}

CS0150 A constant value is expected.

Solution 3 - C#

Now you can use nameof:

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{
    string dataSourceName = typeof(T).Name;
    switch (dataSourceName)
    {
        case nameof(CustomerDetails):
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}

nameof(CustomerDetails) is basically identical to the string literal "CustomerDetails", but with a compile-time check that it refers to some symbol (to prevent a typo).

nameof appeared in C# 6.0, so after this question was asked.

Solution 4 - C#

There is this trick which was shared with me (don't ask for details - won't be able to provide them, but it works for me):

switch (variable_1)
{
    case var value when value == variable_2: // that's the trick
        DoSomething();
        break;
    default:
        DoSomethingElse();
        break;
}

Solution 5 - C#

You can't use a switch statement for this as the case values cannot be evaluated expressions. For this you have to use an an if/else ...

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    if(string.Compare(dataSourceName, typeof(CustomerDetails).Name.ToString(), true)==0)
    {
        var t = 123;
    }
    else if (/*case 2 conditional*/)
    {
        //blah
    }
    else
    {
        //default case
        Console.WriteLine("Test");
    }
}

I also took the liberty of tidying up your conditional statement. There is no need to cast to string after calling ToString(). This will always return a string anyway. When comparing strings for equality, bare in mind that using the == operator will result in a case sensitive comparison. Better to use string compare = 0 with the last argument to set case sensitive on/off.

Solution 6 - C#

This seems to work for me at least when i tried on visual studio 2017.

public static class Words
{
     public const string temp = "What";
     public const string temp2 = "the";
}
var i = "the";

switch (i)
{
  case Words.temp:
    break;
  case Words.temp2:
    break;
}

Solution 7 - C#

switch is very picky in the sense that the values in the switch must be a compile time constant. and also the value that's being compared must be a primitive (or string now). For this you should use an if statement.

The reason may go back to the way that C handles them in that it creates a jump table (because the values are compile time constants) and it tries to copy the same semantics by not allowing evaluated values in your cases.

Solution 8 - C#

Johnnie, Please go through msdn guide on switch. Also, the C# language specification clearly defines the compile time error case:

> • If the type of the switch expression is sbyte, byte, short, ushort, > int, uint, long, ulong, bool, char, string, or an enum-type, or if it > is the nullable type corresponding to one of these types, then that is > the governing type of the switch statement. > > • Otherwise, exactly one user-defined implicit conversion (§6.4) must > exist from the type of the switch expression to one of the following > possible governing types: sbyte, byte, short, ushort, int, uint, long, > ulong, char, string, or, a nullable type corresponding to one of > those types. > > • Otherwise, if no such implicit conversion exists, or if more than > one such implicit conversion exists, a compile-time error occurs.

Hope this helps.

Solution 9 - C#

This does require the latest or close to latest version of C#. The advantage is that the variable 'value' in this example can be manipulated, like this,

   switch (args[1])

                {
                    case var value when string.Equals(value, "SELECT_ALL", StringComparison.OrdinalIgnoreCase):
{
....
break;
}
   case var value when string.Equals(value, "UNSELECT_ALL", StringComparison.OrdinalIgnoreCase):

                        {
...
...
break;
}

etc. etc.

which makes sure that you never match to the wrong literal, in this case, because you forgot to use ToUpper() or whatever...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjohnnieView Question on Stackoverflow
Solution 1 - C#deepee1View Answer on Stackoverflow
Solution 2 - C#Maximilian MayerlView Answer on Stackoverflow
Solution 3 - C#0xFView Answer on Stackoverflow
Solution 4 - C#MjHView Answer on Stackoverflow
Solution 5 - C#iDevForFunView Answer on Stackoverflow
Solution 6 - C#KoreyView Answer on Stackoverflow
Solution 7 - C#Jesus RamosView Answer on Stackoverflow
Solution 8 - C#AksharRoopView Answer on Stackoverflow
Solution 9 - C#AllenView Answer on Stackoverflow