2015-10-05 3 views
2

У меня есть метод с использованием длинной строки инструкций if/elseif (около 10-15), и я понимаю, что, когда вы заканчиваете около 5 команд if if else, лучше использовать переключатель. При этом я не уверен, что могу использовать оператор 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() 
{ 
    case(s.Contains("A")) 
    { 
     //do stuff 
    } 
} 

Но каждый путь я попытался результаты в синтаксической ошибки.

Есть ли способ использовать оператор switch при тестировании строки с помощью метода Contains()?

+6

Нет, Операторы switch требуют постоянных значений для ярлыков case. – 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 заявления.

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 для определенного материала, обычно предупреждает меня о том, как использовать перечисленные ниже возможности для гибкости позже, если вы можете использовать его в своем сценарии. я бы, вероятно, сделать что-то вроде этого:

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

Таким образом, условия тестирования/действия сгруппированы вместе, вы можете аккуратно работать по всем правилам с Еогеасп без особого труда, и добавление/удаление правил проще.

+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

Следует отметить, что 'else' после' if (first! = Null) 'находится там, где будет обрабатываться случай по умолчанию. – juharr

+0

@juharr Ах да, хорошая точка. –

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