C # Сравнение стенографий - PullRequest
3 голосов
/ 18 января 2011

У меня есть этот код:

    if (y == a && y == b && y == c && y == d ...)
    {
        ...
    }

Есть ли какая-то форма сокращения, чтобы я мог переписать ее примерно так?

    if(y == (a && b && c && d ...))
    {
        ...
    }

Функциональность должна быть точно такой же. Я просто ищу что-то менее запутанное.

РЕДАКТИРОВАТЬ Извините, что не уточнил, все переменные являются целыми числами. Я ищу более короткий способ убедиться, что a, b, c, d, ... все равны y.

Ответы [ 9 ]

9 голосов
/ 18 января 2011

Ближайшее, что вы получите (без реализации собственного механизма):

if (new[] { a, b, c, d }.All(value => y == value))
    // ...
4 голосов
/ 18 января 2011

Нет , нет ничего, что упростит ваш код, не перевесив преимущества читабельности с большим снижением производительности.


Редактировать: Высокопроизводительное решение

Если вы достаточно отчаянны, чтобы попробовать высокопроизводительное решение, вот один из них:

(Обновление: очевидно, я ошибался, полагая, что вы можете использовать дженерики с varargs;может только жестко кодировать типы. Поэтому я изменил тип ниже на int вместо этого, но тот же код применяется.)

static bool AllEqual(int value, __arglist)
{
    for (var ai = new ArgIterator(__arglist); ai.GetRemainingCount() > 0; )
    {
        var next = __refvalue(ai.GetNextArg(typeof(int).TypeHandle), int);
        if (!value.Equals(next)) { return false; }
    }
    return true;
}

Затем попробуйте вызвать его с помощью:

//...
bool equal = AllEqual(1, __arglist(1, 1, 1));

Предупреждение: люди, вероятно, будут кричать на вас за это, поэтому используйте это на свой страх и риск.:)

3 голосов
/ 18 января 2011

Немного более читабельно (на мой взгляд):

if ((y == a) && (y == b) && (y == c) && (y == d) ...)

, но я не верю, что для этого есть что-то на базовом языке.

Есливы действительно хотите что-то вроде того, что вы предлагаете, вот для чего нужны функции, что-то вроде:

if (isSetToAll (y, a, b, c, d, ...))

, но вы, возможно, захотите быть осторожными в области производительности.*

Одна вещь может быть полезной для вас, если это делается в цикле, где a/b/c/d/... инвариантны (другими словами, где меняется только y).

Проверьте равенство для инвариантов вне цикла:

if ((a == b) && (a == c) && (a == d) ...)

, потому что, если это не так, то y никогда не может быть равен всем им.Затем внутри цикла просто выполните:

if (y == a)

Тот факт, что вы уже знаете, что все переменные, не являющиеся y, равны друг другу, означает, что вам нужно проверять только y на одномиз них.

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


Я должен упомянуть об этом, хотя и многословнонет ничего на самом деле нечитаемого в вашем исходном коде, особенно если он хорошо отформатирован.Даже чудовище:

if ((y == a) && (y == b) && (y == c) && (y == d) &&
    (y == e) && (y == f) && (y == g) && (y == h) &&
    (y == i) && (y == j) && (y == k) && (y == l) &&
    (y == m) && (y == n) && (y == o) && (y == p) &&
    (y == q) && (y == r) && (y == s) && (y == t) &&
    (y == u) && (y == v) && (y == w) && (y == x))
{
    ...
}

доступно для чтения (хотя я не большой поклонник кратких имен переменных).

Конечно, в этот момент вы можете захотеть использоватьмассивы с циклами, а не с сингулярными переменными.

2 голосов
/ 18 января 2011

Нет, нет.Придерживайтесь того, что у вас есть.

Ну, вы могли бы написать public static bool AllEqual<T>(params T[] values) (возможно, с перегрузками для 2/3/4/5 операндов, чтобы избежать создания массива), но я не уверен, что это стоитэто большинство раз.

1 голос
/ 18 января 2011

Попробуйте это:

Если вы сравниваете строки

IList<string> valuesToCompare = new List<string> { "a", "b", "c", "d" };

if (valuesToCompare.Any(valueToCompare => valueToCompare != y)) 
       //If there is any value that is not equal to y
       //Do something
0 голосов
/ 18 января 2011

Хотя невозможно быть уверенным, я посмотрю на вашу общую структуру кода и выясню, есть ли лучший способ обработать всю эту область.

Каждый раз, когда у вас есть шаблон, который повторяетсятаким образом, вам, вероятно, придется его сильно модифицировать.Скорее всего, вам нужно будет добавить новую q == y или что-то изменить в конце концов.

Многие люди были обеспокоены производительностью, но гораздо важнее убедиться, что ваш код поддерживается и понятен, иправильно учтено.

В качестве общего предположения я бы сказал, что все ваши переменные a, b, c, d должны быть членами 4 различных объектов: ax, bx, cx, dx, что делают a, b, c, d представляют?Они не могут быть просто произвольными числами, они являются ценами или местоположениями в пикселях или весами элементов - что-то!Я не могу представить себе состояние, при котором у вас было бы ровно 4, а не 5 или 3 чего-либо.

В любом случае, что бы это ни представляло, с этим, вероятно, связаны другие вещи - имя, размер, цвет, контрольный индекс - что угодно.

В общем, я бы посмотрел на более высоком уровне для решения этой проблемы.Я бы сказал, что по крайней мере a, b, c & d должны быть определены вне программы, либо в файле данных, либо в базе данных.

0 голосов
/ 18 января 2011
   bool  x=true ,y=true, z=true, p = true;

    if (x == (y == z == p)) //true

    x = false;
    if (x == (y == z == p)) //false
0 голосов
/ 18 января 2011

Для , если (y == a && y == b && y == c && y == d) , используйте:

если (y == a == b == c == d) { // код здесь }

Для , если (y == a || y == b || y == c || y == d) и y - простой тип или строка, используйте:

switch(y)
{
   case a:
   case b:
   case c:
   case d:
     //your code here
     break;

}
0 голосов
/ 18 января 2011
new[] { a, b, c, d }.Contains(y)
...