2016-06-15 19 views
1

Я хочу создать выражение с тремя условиямиВыражение.And три условия

Но Linq.Expressions.Expression.And может принимать только два выражения.

Я хотел бы иметь: ВЫРАЖЕНИЕ1 И ВЫРАЖЕНИЕ2 И expression3

Есть ли способ непосредственно в Linq.Expressions, чтобы сделать это?

ответ

1

Вы должны объединить/гнездо их:

Expression.And(
    Expression.And(
    ..., 
    ... 
), 
    ... 
); 
+0

Поскольку все бинарные операторы в C# являются лево-ассоциативными, я бы использовал 'And (And (x, y), z)' вместо 'And (x, And (y, z))'. – Heinzi

+0

В чем отличие «And (And (x, y), z)» и «And (x, And (y, z))' –

+0

@ Azerty123: В этом конкретном случае обе будут иметь одинаковый результат и сторону -эффекты, поскольку двоичный И является ассоциативной операцией, которая не является короткозамкнутой. – Heinzi

0

Используйте And дважды

т.е. (псевдо-код),

And(condition1,And(condition1,condition2)) 
1

В C#, & является бинарным оператором, и выражение tress mirror C#.

Таким образом, C# выражение a & b & c, которое левоассоциативные, на самом деле означает (a & b) & c, и с помощью деревьев выражений:

Expresssion.And(Expression.And(a, b), c) 

Обратите внимание, что если вы имели в виду, чтобы создать дерево выражения для оператора &&, который также делает короткое замыкание, вы должны использовать AndAlso.

Замечание: Самый простой способ узнать, как построить деревья выражений, - это использовать сам компилятор C#. Например, просто скомпилировать этот кусок кода:

Expression<Func<bool>> e =() => a & b & c; 

и исследовать полученную сборку в инструменте декомпилятора (такие как ILSpy). Просто не забудьте отключить любые оптимизации, которые обрабатывают деревья выражений обратно в код.

-1

В ответах, которые вы предоставили, стоит ответить на вопрос, но я чувствую, что лучше задать вопрос: как подать заявку n условия?

Вы можете сделать это, используя метод Aggregate, который может применить к вашим наборам набор условий. Пример:

//values to filter 
var values = new int[] { 1, 10, 46, 51, 58, 92, 105, 110 }.AsQueryable(); 
var filters = new Expression<Func<int, bool>>[] { 
    i => i % 2 == 0, // integer is even 
    i => i > 50,  // integer is greater than 50 
    i => i < 100  // integer is less than 100 
}; 
var result = filters.Aggregate(values, (current, expression) => current.Where(expression)); 
//result is { 58, 92 } 

Это элегантное решение для большинства ситуаций, связанных с применением нескольких фильтров к набору значений.

+0

Причины для downvotes, кто-нибудь? – Daniel