Ответ 1
См. Ограничения оператора С# - почему?
В основном коммутаторы не могут оценивать утверждения в выражении 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");
}
}
Но это не работает. Оператор case дает мне сообщение о том, что ожидается постоянная переменная. Пожалуйста, помогите, ребята, спасибо!
См. Ограничения оператора С# - почему?
В основном коммутаторы не могут оценивать утверждения в выражении 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 Ожидается постоянное значение.
Вы не можете использовать оператор 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 с последним аргументом, чтобы установить чувствительность к регистру вкл/выкл.
Джонни, пожалуйста, пройдите через подсказку 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, строка или тип с нулевым значением, соответствующий одному из этих типов.
• В противном случае, если такое неявное преобразование не существует или существует более одного такого неявного преобразования, возникает ошибка времени компиляции.
Надеюсь это поможет.
переключатель очень разборчив в том смысле, что значения в коммутаторе должны быть постоянной времени компиляции. а также сравниваемое значение должно быть примитивным (или сейчас). Для этого вы должны использовать оператор if.
Причина может вернуться к тому, что C обрабатывает их тем, что создает таблицу перехода (поскольку значения являются константами времени компиляции) и пытается скопировать одну и ту же семантику, не позволяя оценивать значения в ваших случаях.
Похоже, это работает для меня, по крайней мере, когда я попробовал на 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;
}
Теперь вы можете использовать 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, поэтому после этого был задан вопрос.