Переключить регистр в C # - ожидается постоянное значение - PullRequest
47 голосов
/ 29 сентября 2011

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

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

Ответы [ 7 ]

29 голосов
/ 29 сентября 2011

См. Ограничения оператора переключателя C # - почему?

По сути, Switches не может иметь оцененные операторы в операторе case.Они должны быть статически оценены.

26 голосов
/ 29 сентября 2011

Вы можете соответствовать только константам в операторах 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 голосов
/ 29 сентября 2011

Вы не можете использовать оператор 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() нет необходимости приводить к строке.Это всегда будет возвращать строку в любом случае.При сравнении строк на равенство помните, что использование оператора == приведет к чувствительному к регистру сравнению.Лучше использовать строку сравнения = 0 с последним аргументом для включения / выключения с учетом регистра.

3 голосов
/ 16 марта 2019

Мне кажется, это работает, по крайней мере, когда я пробовал на 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 голосов
/ 29 сентября 2011

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

• Если тип выражения переключения sbyte, byte, short, ushort, int, uint, long, ulong, bool, char, string или enum-type, или, если это это обнуляемый тип, соответствующий одному из этих типов, то это управляющий тип оператора switch.

• В противном случае, точно одно пользовательское неявное преобразование (§6.4) должно существуют от типа выражения переключения до одного из следующих возможные типы управления: sbyte, byte, short, ushort, int, uint, long, ulong, char, string или обнуляемый тип, соответствующий одному из эти типы.

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

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

2 голосов
/ 29 сентября 2011
Переключатель

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

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

1 голос
/ 27 апреля 2019

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

...