2016-01-22 51 views
6

我正在使用Switch語句以及兩個需要查看值是否以特定值開始的條件。 Switch語句的確如此。錯誤說「不能隱藏類型布爾到字符串」。在Switch語句中使用.StartsWith?

任何人都知道我是否可以在交換機中使用StartsWith,或者是否需要使用If ... Else語句?

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

由於switch表達式是一個字符串,因此case標籤必須是字符串;然而,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

感謝您的建議。看到不同的編碼方式以獲得相同的結果總是很好的。我不會考慮使用正則表達式。順便說一句:在我的情況下,*實際上是數據的一部分,並沒有被用作通配符。 – 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"; 
} 

優勢

  • 如果你需要一個新的規則,可以很容易地添加到規則集。
  • 如果您需要新的模式匹配功能,再次輕鬆添加。
  • 如果規則更改,則不需要大量返工。

缺點

  • 新手/初學者,甚至一些中間開發商可能沒有一個線索是怎麼回事。

改進

  • 與表示一個Rule
+0

非常好。我在[我的回答](https://stackoverflow.com/a/48014215/1497596)中提出了一個適度的變化,這可能會吸引那些對使用LINQ感興趣的人。 – DavidRR

2

隨着LINQ,the nice answer by @seriesOne可以是 「簡化」 位通過用替換foreachreturn語句的語義對象替換Tuple<string, string, Func<string, string, bool>>

// 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