LINQ Где () одинарные или двойные трубы / амперсанды - PullRequest
6 голосов
/ 01 августа 2009

Кто-нибудь хочет прокомментировать, должны ли мы использовать «I» или «II» и «&» или «&&» в наших расширениях / запросах LINQ Where ()? Есть ли разница с LINQ to SQL? Получившееся дерево выражений - это больше, чем я могу обдумать в пятницу днем ​​

Спасибо

static void Main(string[] args)
{
    var numbers = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    var q1 = numbers.Where(i => i == 1 | i == 2);
    var q2 = numbers.Where(i => i == 1 || i == 2);

    var q3 = numbers.Where(i => i == 1 & i < 3);
    var q4 = numbers.Where(i => i == 1 && i < 3);

    Write(q1);
    Write(q2);
    Write(q3);
    Write(q4);
}

static void Write<T>(IEnumerable<T> t)
{
    foreach (var i in t)
        Console.Write("{0} ", i);

    Console.WriteLine();
}


Results:

    1 2
    1 2
    1
    1

Ответы [ 4 ]

9 голосов
/ 01 августа 2009

Вы хотите || / &&.

Ну, однотрубный (| / &) обычно используется для побитовой арифметики, и (среди других проблем) может усложнить понимание кодовой базы; он будет работать в LINQ-to-Objects (поскольку по-прежнему определяется для bool), но без обычного короткого замыкания. Но если ваш источник данных - это база данных (т. Е. В миксе есть анализатор выражений), вы можете обнаружить, что он взрывается на вас.


OK; побитовый, возможно, вводил в заблуждение; но || и && остается наиболее логичным и ожидаемым способом выражения ваших намерений. Приношу свои извинения за путаницу.

4 голосов
/ 01 августа 2009

Кто-нибудь хочет прокомментировать, должны ли мы использовать | или || и & или && в наших расширениях / запросах LINQ Where ()?

В лямбда-выражениях (таких как те, которые часто используются в Linq) эти операторы действуют как обычно в c #. | и & - логические операторы, в то время как || и && - логические операторы с коротким замыканием. Короткое замыкание хорошо, если вы хотите эффективный код. Короткое замыкание плохо, если вы хотите избежать кода ветвления (возможно, для UnitTest со 100% покрытием). Большинство людей используют короткие замыкания все время, и ветвление их не беспокоит, потому что они избегают использования выражений, которые имеют побочные эффекты, поэтому они не несут вредных последствий, когда некоторые выражения не оцениваются.

Вот пример полезного ветвления при коротком замыкании:

if (DatabaseIsAvailable() && QueryDataAndThereAreResults())
{
  //do something with Results
}

Если DatabaseIsAvailable () имеет значение false, QueryDataAndThereAreResults () не будет оцениваться.

Есть ли разница с LINQ to SQL?

Неважно, что вы используете для Linq to Sql. Знаки препинания будут переведены в операторы T-Sql AND и OR. После отправки запроса в базу данных оптимизатор плана запросов SqlServer определит, следует ли выполнить короткое замыкание.

1 голос
/ 01 августа 2009

Это все то же самое в вашем примере. | оператор перегружен для типа bool и такой же, как ||

http://msdn.microsoft.com/en-us/library/kxszd0kx.aspx

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

0 голосов
/ 01 августа 2009

Это действительно зависит от ваших предпочтений.

В общем, большинство разработчиков придерживаются || и && для всех логических OR и AND , особенно , когда они имеют дело с кучей чисел в своем коде, как и вы. Это потому, что это визуально сбивает с толку других разработчиков.

Итак, мое мнение - придерживаться || и && для вашей логической работы и использовать только | и & для ваших побитовых операций.

Опять же, хотя это просто предпочтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...