在C#中切换案例 - 预期是一个常量值

问题描述 投票:44回答:7

我的代码如下:

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语句给出了一个错误,说明了一个常量变量。请大家帮忙谢谢!

c# switch-statement
7个回答
29
投票

C# switch statement limitations - why?

基本上,开关不能在case语句中包含evaluate语句。必须对它们进行静态评估。


25
投票

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


例:

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

成功了!


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

CS0150预计值为常数。


8
投票

您不能对此使用switch语句,因为案例值无法计算表达式。为此你必须使用一个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()后无需强制转换为字符串。无论如何,这总是会返回一个字符串。在比较字符串是否相等时,请记住使用==运算符将导致区分大小写的比较。最好使用string compare = 0和最后一个参数来设置区分大小写的开/关。


3
投票

尊尼,请浏览switch上的msdn指南。此外,C#语言规范明确定义了编译时错误情况:

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

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

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

希望这可以帮助。


2
投票

从某种意义上说,switch非常挑剔,因为switch中的值必须是编译时常量。并且被比较的值必须是基元(或现在的字符串)。为此,您应该使用if语句。

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


2
投票

这似乎对我有用,至少当我试用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;
}

0
投票

现在你可以使用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中,所以在提出这个问题之后。

© www.soinside.com 2019 - 2024. All rights reserved.