Есть ли другой способ записать что-то вроде этого:
if (a == x || a == y || a == z)
Один способ, которым я нашел, делает его как это:
if( new [] {x,y,z}.Contains(a))
Есть ли другие хорошие пути?
Я часто использую метод расширения, который имитирует SQL IN
:
public static bool IsIn<T>(this T obj, params T[] collection) {
return collection.Contains(obj);
}
Таким образом я могу сделать
if(a.IsIn(b, c, d)) { ... }
Итак, вы хотите заменить простую эффективную языковую конструкцию, которая содержит оптимизацию короткого замыкания, на что-то гораздо более медленное, что может вызывать исключения?
Однако, если элементы, которые вам нужны, для сравнения не фиксированы по количеству, т.е. во время выполнения это может быть t, u, v, w, x, y, z и т. д., тогда метод Collection.Contains - единственный вариант, но тогда вы ' d будет передавать объекты коллекции, а не отдельные значения, и поэтому выделяется мало памяти.
Если у вас есть большое количество элементов для сравнения «а», но элементы не являются динамическими во время выполнения, то лучше подойдет оператор switch.
У вас есть классический оператор 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)
у вас есть преимущество короткозамкнутого ||
-оператора, поэтому you y и z не будут оцениваться. new [] {x, y, z}
- y и z будет оцениваться каждый раз, . «Уловка» с .Contains ()
была бы более полезной, если бы существовал элегантный синтаксис для создания последовательности с отложенным вычислением ( IEnumerable
). то есть что-то вроде yield return x; yield return y; ...
, но встраиваемый и короче.
Зачем вам еще один способ? Поскольку это не вопрос функциональности, я думаю, дело в том, чтобы улучшить читаемость.
Если у вас есть несколько переменных с осмысленными именами, было бы удобнее просто сравнить, используя ==
. Если у вас их больше, вы можете использовать Содержит
напротив списка, как в другом примере.
Еще один способ - это сравнение с флагами перечисления:
[Flags]
public enum Size
{
Small = 1,
Medium = 2,
Large = 4
}
А затем выяснить, находится ли mySize
в Small
или Medium
:
selectedSizes = Size.Small | Size.Medium;
mySize = Size.Small;
if (mySize & selectedSizes)
{
...
}
Попробуйте это
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();
}
Будьте здоровы.