Linq, если оператор

Как другие уже сказали, порядок, в котором оценены аргументы функции, является неуказанным, и нет никакой точки последовательности между оценкой их. Поскольку Вы изменяетесь pa впоследствии при передаче каждого аргумента, Вы изменяетесь и читаете pa дважды промежуточные две точки последовательности. Это - на самом деле неопределенное поведение. Я нашел очень хорошее объяснение в руководстве GCC, которое я думаю, могло бы быть полезным:

стандарты C и C++ определяют порядок, в котором выражения в программе C/C++ оценены с точки зрения точек последовательности, которые представляют частичное упорядочивание между выполнением частей программы: выполняемые перед точкой последовательности и выполняемыми после него. Они происходят после оценки полного выражения (то, которое не является частью большего выражения), после оценки первого операнда & & ||?: или, (запятая) оператор, прежде чем функция вызвана (но после оценки ее аргументов и выражения, обозначающего вызванную функцию), и в определенных других местах. Кроме, как выражено правилами точки последовательности, не определяется порядок оценки подвыражений выражения. Все эти правила описывают только частичный порядок, а не общий порядок, с тех пор, например, если две функции вызваны в рамках одного выражения без точки последовательности между ними, порядок, в котором вызваны функции, не определяется. Однако комитет по стандартам постановил, что вызовы функции не накладываются.

Это не определяется, когда между модификациями точек последовательности к значениям объектов вступают в силу. Программы, поведение которых зависит от этого, имеют неопределенное поведение; C и стандарты C++ определяют, что “Between предыдущая и следующая точка последовательности объект должна изменить его хранимую сумму самое большее однажды оценка выражения. Кроме того, предшествующее значение должно быть только для чтения для определения значения, которое будет сохранено. ”. Если программа нарушает эти правила, результаты на какой-то конкретной реализации совершенно непредсказуемы.

Примеры кода с неопределенным поведением = ++; [n] = b [n ++] и [я ++] = я;. некоторые более сложные случаи не диагностированы этой опцией, и она может дать случайный ложный положительный результат, но в целом это было найдено довольно эффективным при обнаружении этого вида проблемы в программах.

стандарт сформулирован смутно, поэтому существуют некоторые дебаты по точному значению правил точки последовательности в тонких случаях. Ссылки на обсуждения проблемы, включая предложенные формальные определения, могут быть найдены на странице чтений GCC, в http://gcc.gnu.org/readings.html .

7
задан Aamir 18 September 2009 в 08:10
поделиться

3 ответа

Я бы использовал здесь точечную нотацию:

var query = questions.Where(q => !q.IsDeleted);

if (catId != 0)
{
    query = query.Where(q => cats.Contains(q.CatID));
}
if (authorId != 0)
{
    query = query.Where(q => q.OwnerId == authorId);
}

Вы могли бы написать свой собственный метод расширения, чтобы сделать это немного проще:

public static IQueryable<T> OptionalWhere<T>(
    this IQueryable<T> source,
    bool condition, 
    Expression<Func<T,bool>> predicate)
{
    return condition ? source.Where(predicate) : source;
}

Затем вы могли бы написать:

var query = questions.Where(q => !q.IsDeleted);
                     .OptionalWhere(catId != 0, q => cats.Contains(q.CatID))
                     .OptionalWhere(authorId != 0, q => q.OwnerId == authorId);
14
ответ дан 6 December 2019 в 19:39
поделиться

Вы можете условно построить такой запрос:

 var query = from q in questions
             where q.question_isdeleted
             select q;
 if(!string.IsNullOrEmpty(AuthorID))
 {
     query = from q in query
             where q.question_ownerid == AuthorID
             select q;
 }

Однако LINQ to Entities не имеет хорошей конструкции, которая напоминала бы оператор SQL IN ...

0
ответ дан 6 December 2019 в 19:39
поделиться
where question.question_isdeleted = 0
  && (catid != 0 
     ? catsStr.Contains(CatId.ToString())
     : question_ownerId == id)

Не уверен, что строковые операции верны, но логика выглядит правильной.

-1
ответ дан 6 December 2019 в 19:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: