Случай переключения в С# - ожидается постоянное значение

Мой код выглядит следующим образом:

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 дает мне сообщение о том, что ожидается постоянная переменная. Пожалуйста, помогите, ребята, спасибо!

Ответ 2

Вы можете соответствовать только константам в выражениях switch.


Пример:

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

Успешный!


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

CS0150 Ожидается постоянное значение.

Ответ 3

Вы не можете использовать оператор switch для этого, поскольку значения case не могут быть оценены выражениями. Для этого вам нужно использовать if 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 с последним аргументом, чтобы установить чувствительность к регистру вкл/выкл.

Ответ 4

Джонни, пожалуйста, пройдите через подсказку msdn на коммутаторе. Кроме того, спецификация языка С# четко определяет случай ошибки компиляции:

• Если тип выражения коммутатора - это 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, строка или тип с нулевым значением, соответствующий одному из этих типов.

• В противном случае, если такое неявное преобразование не существует или существует более одного такого неявного преобразования, возникает ошибка времени компиляции.

Надеюсь это поможет.

Ответ 5

переключатель очень разборчив в том смысле, что значения в коммутаторе должны быть постоянной времени компиляции. а также сравниваемое значение должно быть примитивным (или сейчас). Для этого вы должны использовать оператор if.

Причина может вернуться к тому, что C обрабатывает их тем, что создает таблицу перехода (поскольку значения являются константами времени компиляции) и пытается скопировать одну и ту же семантику, не позволяя оценивать значения в ваших случаях.

Ответ 6

Похоже, это работает для меня, по крайней мере, когда я попробовал на 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;
}

Ответ 7

Теперь вы можете использовать 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 появилось в С# 6.0, поэтому после этого был задан вопрос.