2016-01-22 4 views
6

Я работаю над оператором Switch и с двумя условиями, которые мне нужны, чтобы увидеть, начинаются ли значения с определенным значением. Оператор Switch делает это. Ошибка говорит: «Нельзя скрывать тип bool для строки».Использование .StartsWith в инструкции Switch?

Кто-нибудь знает, могу ли я использовать StartsWith в Switch или мне нужно использовать If ... Else statements?

switch(subArea) 
      { 
       case "4100": 
       case "4101": 
       case "4102": 
       case "4200": 
        return "ABC"; 
       case "600A": 
        return "XWZ"; 
       case subArea.StartsWith("3*"): 
       case subArea.StartsWith("03*"): 
        return "123"; 
       default: 
        return "ABCXYZ123"; 
      } 
+2

Вам нужно будет использовать if/else. – adv12

+2

Предположим, вы все равно можете использовать переключатель для всех других значений и поместить код StartsWith в случай по умолчанию ... – adv12

ответ

7

Вы переключения String и subArea.StartsWith() возвращает Boolean, поэтому вы не можете это сделать. Я предлагаю вам сделать это следующим образом:

if (subArea.StartsWith("3*") || subArea.StartsWith("03*")) 
    return "123"; 

switch(subArea) 
{ 
    case "4100": 
    case "4101": 
    case "4102": 
    case "4200": 
     return "ABC"; 
    case "600A": 
     return "XWZ"; 
    default: 
     return "ABCXYZ123"; 
} 

Результат будет таким же.

+0

Это сработало! Благодарю. – Caverman

+0

Я предпочитаю это решение, потому что оно не приводит к вложенной логике. – Aphelion

+0

«Результат будет таким же» - при условии, что ни одно из значений в случаях переключения не начинается с «3 *» или «03 *». – Joe

3

Этикетки case должны быть строками, поскольку выражение switch является строкой; однако StartsWith возвращает логическое значение. Я предлагаю обработать эти специальные случаи в разделе default.

switch(subArea) 
{ 
    case "4100": 
    case "4101": 
    case "4102": 
    case "4200": 
     return "ABC"; 
    case "600A": 
     return "XWZ"; 
    default: 
     if (subArea.StartsWith("3") || subArea.StartsWith("03")) { 
      return "123"; 
     } 
     return "ABCXYZ123"; 
} 

Также звезда (*), вероятно, не так, если вы не хотите subArea содержать его. StartWith не принимает подстановочные знаки.

В качестве альтернативы вы можете использовать регулярные выражения:

if (Regex.IsMatch(subArea, "^3|^03")) { // or "^(3|03)" 
    return "123"; 
} 

где ^ означает начало линии и | означает или.

+0

Спасибо за предложение. Всегда полезно видеть разные способы кодирования, чтобы получить те же результаты. Я бы не подумал использовать Regex. Кстати: в моем случае * фактически является частью данных и не использовался в качестве дикой карты. – Caverman

+0

Если вы используете регулярное выражение, не забудьте избежать звезды: '\ *'. –

2

Просто для удовольствия, вот еще одно решение, которое позволяет избежать оператора switch.

var map = new[] { 
    new { Value = "4100", StartsWith = false, Result="ABC" }, 
    new { Value = "4101", StartsWith = false, Result="ABC" }, 
    new { Value = "4102", StartsWith = false, Result="ABC" }, 
    new { Value = "4200", StartsWith = false, Result="ABC" }, 
    new { Value = "600A", StartsWith = false, Result="XWZ" }, 
    new { Value = "3*", StartsWith = true, Result="123" }, 
    new { Value = "03*", StartsWith = true, Result="123" }, 
}; 

var subarea = ... whatever ...; 

var result = map.Where(e => 
     { 
      if (e.StartsWith) 
      { 
       return subarea.StartsWith(e.Value); 
      } 
      else 
      { 
       return subarea == e.Value; 
      } 
     } 
    ) 
    .Select(e => e.Result) 
    .FirstOrDefault() ?? "ABCXZ123"; 

Порядок в массиве map определяет приоритет, так что, к примеру, вы можете иметь точное совпадение, скажем, «3 * 11», а также StartsWith матч на «3 *» , например:

var map = new[] { 
    new { Value = "3*11", StartsWith = false, Result="ABC" }, 
    new { Value = "4100", StartsWith = false, Result="ABC" }, 
    new { Value = "4101", StartsWith = false, Result="ABC" }, 
    new { Value = "4102", StartsWith = false, Result="ABC" }, 
    new { Value = "4200", StartsWith = false, Result="ABC" }, 
    new { Value = "600A", StartsWith = false, Result="XWZ" }, 
    new { Value = "3*", StartsWith = true, Result="123" }, 
    new { Value = "03*", StartsWith = true, Result="123" }, 
}; 
2

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

private static string GetSomeStringOrOther(string subArea) 
{ 
    // Create a set of pattern matching functions... 
    Func<string, string, bool> matchEquals = (a, b) => a.Equals(b); 
    Func<string, string, bool> matchStarts = (a, b) => a.StartsWith(b); 

    // Create a rule set... 
    Tuple<string, string, Func<string, string, bool>>[] cases = new [] 
    { 
     new Tuple<string, string, Func<string, string, bool>>("4100", "ABC", matchEquals), 
     new Tuple<string, string, Func<string, string, bool>>("4101", "ABC", matchEquals), 
     new Tuple<string, string, Func<string, string, bool>>("4102", "ABC", matchEquals), 
     new Tuple<string, string, Func<string, string, bool>>("4200", "ABC", matchEquals), 
     new Tuple<string, string, Func<string, string, bool>>("600A", "XWZ", matchEquals), 
     new Tuple<string, string, Func<string, string, bool>>("3*", "123", matchStarts), 
     new Tuple<string, string, Func<string, string, bool>>("03*", "123", matchStarts), 
    }; 

    // Look for a match... 
    foreach(var matchCase in cases) 
    { 
     if(matchCase.Item3(subArea, matchCase.Item1)) 
     { 
      // Return if it matches... 
      return matchCase.Item2; 
     } 
    } 

    // Otherwise return the default... 
    return "ABCXYZ123"; 
} 

Преимущества

  • Если вам нужно новое правило, легко добавить к набору правил.
  • Если вам нужна новая функция сопоставления рисунка, снова легко добавить.
  • Не требуется обширная переделка, если правило изменяется.

Недостатки

  • Novice/начальный и даже некоторые промежуточные разработчики могут не иметь ни малейшего понятия, что происходит.

Улучшение

  • Заменить Tuple<string, string, Func<string, string, bool>> с семантическим объектом, который представляет собой Rule
+0

Очень приятно. Я предложил небольшую вариацию в [моем ответе] (https://stackoverflow.com/a/48014215/1497596), который может понравиться тем, кто заинтересован в использовании LINQ. – DavidRR

2

С помощью LINQ, the nice answer by @seriesOne может быть "упрощенным" бит, заменив заявления foreach и return с :

// using System.Linq; 

// Look for a match... 
var result = cases 
    .Where(c => c.Item3(subArea, c.Item1)) 
    .FirstOrDefault(); 

// Return the match or the default. 
return result == null ? "ABCXYZ123" : result.Item2; 
+1

Хорошее улучшение. +1 – series0ne

Смежные вопросы