簡體   English   中英

C# 中的開關盒 - 預期為常數值

[英]Switch case in C# - a constant value is expected

我的代碼如下:

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 語句限制 - 為什么?

基本上 Switch 不能在 case 語句中評估語句。 它們必須被靜態評估。

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


例子:

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

成功的!


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

CS0150 應為恆定值。

現在您可以使用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 中,所以在問這個問題之后。

您不能為此使用 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()后無需轉換為字符串。 無論如何,這將始終返回一個字符串。 在比較字符串是否相等時,請記住使用 == 運算符將導致區分大小寫的比較。 最好使用 string compare = 0 和最后一個參數來設置區分大小寫的開/關。

有一個與我分享的技巧(不要詢問細節 - 無法提供它們,但它對我有用):

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

至少當我嘗試使用 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;
}

switch 非常挑剔,因為 switch 中的值必須是編譯時常量。 並且正在比較的值必須是原始值(或現在的字符串)。 為此,您應該使用 if 語句。

原因可能回到 C 處理它們的方式,因為它創建了一個跳轉表(因為這些值是編譯時常量)並且它試圖通過在您的情況下不允許評估值來復制相同的語義。

約翰尼,請閱讀有關switch 的msdn 指南。 此外,C# 語言規范明確定義了編譯時錯誤情況:

• 如果 switch 表達式的類型是 sbyte、byte、short、ushort、int、uint、long、ulong、bool、char、string 或枚舉類型,或者它是與這些類型之一對應的可為空類型,那么這就是 switch 語句的控制類型。

• 否則,從 switch 表達式的類型到以下可能的控制類型之一必須存在一個用戶定義的隱式轉換(第 6.4 節):sbyte、byte、short、ushort、int、uint、long、ulong、char、字符串,或對應於這些類型之一的可為空類型。

• 否則,如果不存在此類隱式轉換,或者存在多個此類隱式轉換,則會發生編譯時錯誤。

希望這可以幫助。

這確實需要最新或接近最新版本的 C#。優點是可以操作此示例中的變量“值”,如下所示,

   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() 或其他......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM