在C#中切换大小写-期望一个恒定值


70

我的代码如下:

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");
    }
}

但这是行不通的。该case语句给我一个错误,表明需要一个常量变量。请大家帮忙谢谢!


Answers:


44

请参阅 C#switch语句限制-为什么?

基本上,Switch不能在case语句中具有评估语句。必须对其进行静态评估。


7
这在VB.net中是不正确的...我正在尝试转换已经具有这种大小写值(基本上是方法调用)的代码
Moslem Ben Dhaou 2015年

6
@Moslem Ben Dhaou是的,C#Switch绝对不等同于VB Case语句。对于Case语句,您可以使用表达式(函数调用,变量等),而C#需要常量值(无函数调用,变量等)。与之相比,switch语句非常有限。
deepee1

36

您只能在switch语句中匹配常量。


例:

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

成功!


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

CS0150期望一个恒定值。


23
另外需要注意的是:“ const int myConstant = 3”算作一个常量,但“只读static int myReadonlyStatic = 3”则不算作常量。
Stachu 2013年

13

您不能为此使用switch语句,因为case值不能被评估为表达式。为此,您必须使用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");
    }
}

我还自由整理了您的条件声明。调用后无需强制转换为字符串ToString()。无论如何,它将始终返回一个字符串。比较字符串是否相等时,请记住,使用==运算符将导致区分大小写的比较。最好在最后一个参数中使用字符串compare = 0来设置区分大小写的开/关。


11

现在您可以使用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)基本上与字符串文字相同"CustomerDetails",但是在编译时检查它是否引用了某个符号(以防止输入错误)。

nameof 出现在C#6.0中,因此在询问了此问题之后。


7

至少当我尝试使用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;
}

3
VS2017无关。Words.temp和Words.temp2仍然是常量。编译Switch语句时,编译器将用其实际值替换“ case值”。只要编译器能够使用常量,就可以正常工作。
泽卡洛斯

3

从某种意义上说,switch的选择必须是一个编译时间常数,因此它非常挑剔。并且要比较的值也必须是原始值(或现在为字符串)。为此,您应该使用if语句。

原因可能回到C处理它们的方式,因为它创建了一个跳转表(因为这些值是编译时间常数),并且它试图通过在您的情况下不允许使用评估值来复制相同的语义。


3

尊尼妮,请仔细阅读switch上的msdn指南。同样,C#语言规范明确定义了编译时错误的情况:

•如果switch表达式的类型是sbyte,byte,short,ushort,int,uint,long,ulong,bool,char,string或enum类型,或者它是与这些类型之一相对应的可空类型,那么这就是switch语句的管理类型。

•否则,从switch表达式的类型到以下可能的控制类型之一,必须存在一个用户定义的隐式转换(第6.4节):sbyte,byte,short,ushort,int,uint,long,ulong,char,字符串,或者对应于这些类型之一的可为空的类型。

•否则,如果不存在此类隐式转换,或者存在多个此类隐式转换,则会发生编译时错误。

希望这可以帮助。


0

有一个与我分享的技巧(不要求提供详细信息-无法提供它们,但对我有用):

switch (variable_1)
{
    case var value when value == variable_2: // that's the trick
        DoSomething();
        break;
    default:
        DoSomethingElse();
        break;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.