2015-10-05 252 views
2

我有一個使用if/elseif語句(大約10-15)的長字符串的方法,並且我知道當您經過大約5個if/else if語句時,最好使用開關。話雖如此,我不確定我可以在我的情況下使用switch語句,因爲我的if/else if語句依賴於測試字符串,而不是相等,但使用Contains()方法。所以,現在我有一些等價的可以將switch語句與string.Contains()一起使用嗎?

string s = "ABCD"; 
if(s.Contains("A") 
{ 
    //do stuff 
} 
else if(s.Contains("E") 
{ 
    //do different stuff 
} 
etc ... 

我已經試過落實switch語句的不同的充方式,如

switch() 
{ 
    case(s.Contains("A")) 
    { 
     //do stuff 
    } 
} 

但每次這樣,我已經試過在一個語法錯誤的結果。

有沒有辦法在使用Contains()方法測試字符串時使用switch語句?

+6

沒有,開關語句需要標籤的常量值。 – juharr

+0

好的。這就是我的想法,但我想確定。謝謝! – BrianH

+0

@BrianH你只想執行'命中'的第一個動作,或者其中字符串包含該子串的所有動作? – Jonesopolis

回答

3

不,switch聲明要求箱標籤的常量值。所以一般來說,你最好堅持使用if聲明。但是,這與您在場景中使用switch聲明差不多。

string myString = "ABC"; 
List<string> subStrings = new List<string>{"A", "B", "C"}; 
switch (subStrings.FirstOrDefault(myString.Contains)) 
{ 
    case "A": 
     Console.WriteLine("Has A"); 
     break; 
    case "B": 
     Console.WriteLine("Has B"); 
     break; 
    case "C": 
     Console.WriteLine("Has C"); 
     break; 
    default: 
     Console.WriteLine("No ABC"); 
     break; 
} 

我懷疑這將是任何比if語句更快,因爲FirstOrDefault,基本上是做同樣的事情,而且因爲它需要更新的列表,並switch聲明它打破了DRY原則。

1

,想到的第一件事是

 string s = "ABCD"; 

     foreach (char oneChar in s.ToCharArray()) 
     { 
      switch (oneChar) 
      { 
       case 'A': 
        Console.WriteLine("Do A stuff"); 
        break; 
       case 'B': 
        Console.WriteLine("Do B stuff"); 
        break; 
       case 'C': 
        Console.WriteLine("Do C stuff"); 
        break; 
       case 'D': 
        Console.WriteLine("Do D stuff"); 
        break; 
       default: 
        break; 
      } 
     } 

取決於你在做什麼,這可能會或可能不會去的有效途徑。如果字符串中的大多數字符實際上會導致分支到這些情況之一,那麼這會更有效,因爲您不必執行一堆包含字符串的搜索。如果字符串中有很多字符沒有匹配的分支(它們什麼都不做),那麼這可能不是一個有效的方法。

+2

我很感謝您的反饋。我用於我的問題的例子只測試一個字符,但在我的實際代碼中,我測試了不同長度的字符串。我對這種混亂表示歉意。 – BrianH

+0

然後我會堅持使用if-elseif語句,除非這是您的代碼中執行很多的一個點。有幾種方法可以削減幾個時鐘,但最有可能不值得。 – AgapwIesu

1

對特定的東西有大量的if/else檢查,通常會提醒我以後可以使用enumerables來獲得靈活性的好地方,如果您可以在您的場景中使用它。我可能會做這樣的事情:

string input = "ABDE"; 
var mapping = new Dictionary<Func<string, bool>, Action<string>>() 
{ 
    { (string i) => i.Contains("A"), (string i) => Console.WriteLine("Found input with 'A'") }, 
    { (string i) => i.Contains("B"), (string i) => Console.WriteLine("Found input with 'B'") }, 
    { (string i) => i.Contains("C"), (string i) => Console.WriteLine("Found input with 'C'") }, 
    { (string i) => i.Contains("D"), (string i) => Console.WriteLine("Found input with 'D'") } 
}; 

foreach (var criteria in mapping) 
{ 
    if (criteria.Key(input)) { 
     criteria.Value(input); 
     break; 
    } 
} 

這樣的測試/動作條件組合在一起,你可以清晰地跑過去所有在foreach規則沒有太多的工作,並添加/刪除規則是容易。

+0

要複製'if-else if-else'行爲,您需要在第一場比賽中休息。如果沒有匹配能夠處理「默認」情況,則必須跟蹤。 – juharr

0

如果您有這些線路很多,有時也可以是更清晰,更靈活地使用字典的目標值動作映射,例如:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     static void Main() 
     { 
      var dict = new Dictionary<string, Action<string>> 
      { 
       ["A"] = Console.WriteLine, 
       ["B"] = doSomething1, 
       ["C"] = doSomething2, 
       ["D"] = str => Console.WriteLine("Inline: " + str) 
      }; 

      string s = "ABCD"; 
      string first = dict.Keys.FirstOrDefault(t => s.Contains(t)); 

      if (first != null) 
       dict[first](first); 
      else 
       ; // Default behaviour. 
     } 

     private static void doSomething1(string x) 
     { 
      Console.WriteLine("doSomething1 with " + x); 
     } 

     private static void doSomething2(string x) 
     { 
      Console.WriteLine("doSomething2 with " + x); 
     } 
    } 
} 

「更靈活」我的意思是如果您想將動作映射到一個地方並在其他地方使用,您可以傳遞字典。

(它使用C#語法6初始化字典。)

說了這麼多,除非你想繞過字典在我看來,一個不必要的併發症。如果你不這樣做,那麼使用if/else級聯可能是最好的方法。

(注意:這個答案是類似於邁克科科倫的 - 我是在同一時間,他是他寫的,看來我會,因爲它需要一個稍微不同的方式離開這裏)

+0

需要注意的是'if(first!= null)'後面的'else'是處理「默認」情況的地方。 – juharr

+0

@juharr啊,是的,好點。 –

相關問題