C# 中的开关大小写 - 需要一个常量值

发布于 2024-12-07 07:05:46 字数 389 浏览 0 评论 0原文

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 语句给出需要常量变量的错误?

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

Why is the case statement giving an error that a constant variable is expected?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

§对你不离不弃 2024-12-14 07:05:47

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

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;
}
囍孤女 2024-12-14 07:05:47

switch 非常挑剔,因为 switch 中的值必须是编译时常量。并且正在比较的值必须是原语(或现在的字符串)。为此,您应该使用 if 语句。

原因可能要追溯到 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.

樱花落人离去 2024-12-14 07:05:47

Johnnie,请阅读有关 switch 的 msdn 指南。另外,C# 语言规范明确定义了编译时错误情况:

• 如果 switch 表达式的类型为 sbyte、byte、short、ushort,
int、uint、long、ulong、bool、char、string 或枚举类型,或者如果
是与这些类型之一对应的可空类型,那么就是
switch 语句的控制类型。

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

• 否则,如果不存在此类隐式转换,或者超过
存在这样一个隐式转换,就会发生编译时错误。

希望这有帮助。

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.

北笙凉宸 2024-12-14 07:05:47

这确实需要最新或接近最新版本的 C#。优点是这个例子中的变量“value”可以被操纵,就像这样,

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

等等。
等等,

这确保您永远不会匹配错误的文字,在这种情况下,因为您忘记使用 ToUpper() 或其他...

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...

卸妝后依然美 2024-12-14 07:05:46

有一个与我分享的技巧(不要询问细节 - 将无法提供它们,但它对我有用):

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

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;
}
贪了杯 2024-12-14 07:05:46


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

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

See
C# switch statement limitations - why?

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

尐偏执 2024-12-14 07:05:46

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


示例:

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

成功!


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

CS0150 需要一个常量值。

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.

叫嚣ゝ 2024-12-14 07:05:46

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

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.

少女净妖师 2024-12-14 07:05:46

您不能为此使用 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() 后无需转换为字符串。无论如何,这总是会返回一个字符串。比较字符串是否相等时,请记住使用 == 运算符将导致比较区分大小写。最好使用字符串比较 = 0 和最后一个参数来设置区分大小写的开/关。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文