2016-01-22 11 views
6

私は、Switch文と、値が特定の値で始まるかどうかを確認するために必要な2つの条件について取り組んでいます。 Switchステートメントは、このようになります。エラーは "bool型を文字列に変換できません"と表示します。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

スイッチ式が文字列であるため、ケースラベルは文字列でなければなりません。ただし、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」、優先順位を決定し、同様に「3 *」にStartsWith試合例えば:

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"; 
} 

利点

  • 新しいルールが必要な場合は、ルール・セットに追加するのは簡単です。
  • 新しいパターンマッチング機能が必要な場合は、再び簡単に追加できます。
  • ルールが変更された場合、大幅な再作業は必要ありません。

デメリット

  • /初級、さらにいくつかの中間の開発者初心者は何が起こっているの手掛かりを持っていない可能性があります。

改善

  • LINQでRule
+0

非常に良い。私は[私の答え](https://stackoverflow.com/a/48014215/1497596)で、LINQの使用に興味のある人に魅力的かもしれない穏やかなバリエーションを提案しました。 – DavidRR

2

を表すセマンティックオブジェクトとTuple<string, string, Func<string, string, bool>>を置き換え、the nice answer by @seriesOneはでforeachreturn文を置き換えることによってビット "簡略化" することができます:

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

関連する問題