2013-05-31 3 views
31

Есть более короткий путь писать что-то вроде этого: Проверьте, является ли переменная в одноранговой списке значений

if(x==1 || x==2 || x==3) // do something 

Что я ищу что-то вроде этого:

if(x.in((1,2,3)) // do something 
+6

'if (x> = 1 && x <= 3)'? – vcsjones

+3

Что случилось с вашим путем? У вас есть еще много * сравнений? Потому что первая (всего лишь 3 или даже 4 сравнения) обычно более читаема, чем последняя. – dlev

+2

Что случилось с первым? Он достаточно короткий, объясняет себя и так же эффективен, как и вы. –

ответ

29

Вы могли бы добиться этого с помощью List.Contains метода:

if(new []{1, 2, 3}.Contains(x)) 
{ 
    //x is either 1 or 2 or 3 
} 
+0

Это хорошо, поскольку он выходит из массива generic. – RacerNerd

+0

Я положил это в том же классе – user1854438

+0

Прекрасное спасибо! – user1854438

0

Я полностью угадывание здесь, правильно т он код, если я ошибаюсь:

(new int[]{1,2,3}).IndexOf(x)>-1 
28
public static bool In<T>(this T x, params T[] set) 
{ 
    return set.Contains(x); 
} 

... 

if (x.In(1, 2, 3)) 
{ ... } 

Необходимое чтение: MSDN Extension methods

+1

+1 Наилучший ответ – Isaac

+5

Можно даже обновить это, чтобы использовать 'params', чтобы вы получили что-то вроде' x.In (1, 2, 3) 'EDIT: Конечно, в этот момент вы должны написать' x.In () ', что немного глупо. (с другой стороны, избегает существующей версии 'IEnumerable ', где вы можете передать« x.In (null) »и выбросить исключение) –

+2

Может быть, лучше, вы слышали о' params'? –

11

Если это в IEnumerable<T>, используйте:

Else, вот краткий метод расширения:

public static bool In<T>(this T value, params T[] input) 
{ 
    return input.Any(n => object.Equals(n, value)); 
} 

Положите его в static class, и вы можете использовать его как это:

if (x.In(1,2,3)) //whatever 
+0

И снова FGITW! ** Ugh. ** –

+0

+1 на самом деле это тоже хорошо – Isaac

+0

Я думаю, что вы хотите 'n => object.Equals (n, value)', поскольку a), который защищает от 'null 'и b) гарантирует, что неценные типы имеют шанс при равенстве значений. (Я думаю, что использование' Contains() 'вместо' Any() 'выполнит одно и то же). – dlev

-2

Вы можете создать простой Dictionary<TKey, TValue>, который будет использоваться в качестве Decision Table для этой проблемы:

 //Create your decision-table Dictionary 
     Action actionToPerform1 =() => Console.WriteLine("The number is okay"); 
     Action actionToPerform2 =() => Console.WriteLine("The number is not okay"); 
     var decisionTable = new Dictionary<int, Action> 
      { 
       {1, actionToPerform1}, 
       {2, actionToPerform1}, 
       {3, actionToPerform1}, 
       {4, actionToPerform2}, 
       {5, actionToPerform2}, 
       {6, actionToPerform2} 
      }; 

     //According to the given number, the right *Action* will be called. 
     int theNumberToTest = 3; 
     decisionTable[theNumberToTest](); //actionToPerform1 will be called in that case. 

После того, как вы инициализировали свой Dictionary, все, что нужно сделать, это:

decisionTable[theNumberToTest]();

+0

Это один из самых маленьких отдельных элементов надстройки, которые я когда-либо видел. Учитывая контекст. –

+0

Это один из самых чистых и быстрых методов. Это все, что вам нужно сделать, чтобы выполнить условие 'if':' decisionTable [theNumberToTest](); ' –

+1

Мне нравится, когда люди используют O (?), Чтобы попытаться доказать, что что-то« быстрее », чем другое. Он пахнет свежим мясом с намеком на мяту. – NPSF3000

-3

Этот ответ относится к возможной будущей версии C# ;-) Если рассмотреть вопрос о переходе на Visual Basic, или если Microsoft, наконец, решает ввести Select заявление Case для C#, она будет выглядеть следующим образом:

Select Case X 
    Case 1, 2, 3 
    ... 
End Select 
Смежные вопросы