Есть ли другой способ написать что-то вроде этого:
if (a == x || a == y || a == z)
Один из способов, который я нашел, делает это следующим образом:
if( new [] {x,y,z}.Contains(a))
Есть ли другие хорошие способы?
Есть ли другой способ написать что-то вроде этого:
if (a == x || a == y || a == z)
Один из способов, который я нашел, делает это следующим образом:
if( new [] {x,y,z}.Contains(a))
Есть ли другие хорошие способы?
Я часто использую метод расширения, который имитирует SQLs IN
:
public static bool IsIn<T>(this T obj, params T[] collection) {
return collection.Contains(obj);
}
Таким образом, я могу сделать
if(a.IsIn(b, c, d)) { ... }
У вас есть классический оператор switch:
switch(a) {
case x:
case y:
case z:
// Do stuff
break;
}
Просто для удовольствия:
using System;
static class Program {
static bool In(this object obj, params object[] values) {
foreach (object value in values) {
if (obj.Equals(value)) {
return true;
}
}
return false;
}
static void Main(string[] args) {
bool test1 = 3.In(1, 2, 3);
bool test2 = 5.In(1, 2, 3);
}
}
Но я действительно думаю, что лучший способ - написать обычную проверку
if(a == x || a == y || a == z)
Как все сразу поймут, что он делает.
Ваше решение переписать его как
if( new [] {x,y,z}.Contains(a))
не является хорошим шагом.
Вы используете простую эффективную логическую операцию, которую каждый программист легко понимает и которая содержит короткозамкнутую логику, чтобы ускорить ее, и вместо этого вы создали код, который требует момента, чтобы понять и который значительно менее эффективен.
Иногда ваши коллеги-инженеры предпочитают это, если вы не пытаетесь быть "умными"!
Рассмотрим случай, когда a == x, а y и z являются медленно оцениваемыми, дорогие функции.
if(a == x || a == y || a == z)
у вас есть преимущество короткого замыкания ||
-оператор, поэтому вы y и z не будете оцениваться.new[] { x, y, z }
- y и z, будет оцениваться каждый раз. "Трюк" с .Contains()
был бы более полезен, если бы был элегантный синтаксис для создания последовательности с ленивой оценкой (IEnumerable<T>
). то есть что-то вроде yield return x; yield return y;...
, но вложенное и более короткое.
Итак, вы хотите заменить простую, эффективную конструкцию языка, которая содержит оптимизацию короткого замыкания во что-то гораздо более медленное, которое может генерировать исключения?
Однако, если элементы, которые вы хотите сравнить, не фиксированы в количестве, то есть во время выполнения это могут быть t, u, v, w, x, y, z и т.д., тогда коллекция. метод является единственным вариантом, но тогда вы будете передавать объекты коллекции вокруг, а не отдельные значения, и поэтому есть небольшое количество ресурсов памяти ovrehead.
Если у вас есть большое количество элементов для сравнения "a", но элементы не динамичны во время выполнения, тогда оператор switch лучше подходит.
Зачем вам нужен еще один способ? Поскольку это не вопрос функциональности, я бы предположил, что дело в улучшении читаемости.
Если у вас есть несколько переменных со значимыми именами, было бы легче читать, используя ==
. Если у вас есть больше, вы можете использовать Contains
для списка, как в вашем другом примере.
Еще один способ - сравнить с флажками enum:
[Flags]
public enum Size
{
Small = 1,
Medium = 2,
Large = 4
}
И затем, чтобы узнать, находится ли mySize
в Small
или Medium
:
selectedSizes = Size.Small | Size.Medium;
mySize = Size.Small;
if (mySize & selectedSizes)
{
...
}
if(a==x?true:a==y?true:a==z?true:false)
Попробуйте это
var res2 = new[] { 1, 2, 3 }.Any(x => x == 2);
Например, ваша логика такова:
if(a==x || a== y|| a==z)
{
DoSomething();
}
else
{
DoOtherThings();
}
будет эквивалентно:
if(a!=x&& a != y && a!= z)
{
DoOtherThings();
}
else
{
DoSomething();
}
Приветствия.