Как параметры предиката работают синтаксически в C #? - PullRequest
3 голосов
/ 11 августа 2009

Некоторые инфраструктуры объектного реляционного сопоставления (ORM) (такие как LLBLGen) позволяют указывать параметры «предиката» для методов запроса, например (немного упрощенный):

var entities = adapter.FetchEntities(EntityType.Employee,
    EmployeeFields.Salary > 50000);

Как этот второй параметр работает синтаксически в C #? Это выглядит как лямбда-выражение, но в нем нет части параметра или «=>». Что это? Может понадобиться Джон Скит для этого.

Ответы [ 2 ]

6 голосов
/ 11 августа 2009

Если вы перегрузили оператор ">", чтобы вернуть какой-то объект предиката для вашего специального типа "SuperDatabaseMapField", вы могли бы сделать такие вещи.

Тем не менее, кажется, что во всех отношениях кажется, что взятие лямбда-выражения (и, если нужно, парсинг дерева выражений) значительно хуже

2 голосов
/ 11 августа 2009

Я согласен с mquander's ответом. Причина такой конструкции в том, как компиляторы оценивают выражения. В этом случае для LLBLGen второй параметр ожидает что-то, что может быть оценено как логическое (например).

Операторы (+, -, ***, /) - это просто выражения, которые компилятор использует для построения деревьев синтаксиса, которые он использует для проверки правильности определенных комбинаций левого и правого выражений с учетом контекста ("+"). Например, a (строковый литерал) + 2.4 (с плавающей точкой) явно недопустим в C #, и компилятор знает это по проверке выражений (строка) (operator_add) (флоат) .

Поэтому, чтобы создать странный сценарий, подобный следующей работе:

FetchEntities(EntityType.Employee, 
    EmployeeFields.Salary > ((EmployeeFields.DateOfBirth - 10) * 1.2) + 1024)

необходимо перегрузить операторы (- и *** и +) для возврата нового объекта-предиката.

В конечном итоге такое утверждение будет преобразовано в следующее синтаксическое дерево (элементы в «()» являются типами выражений для целей этого ответа)

(BinaryComparison)
    LeftSide: (Field_Reference)    --> EmployeeFields.Salary
    RightSide:
        (MathematicOperator)
            LeftSide:
                (MathematicOperator)
                    LeftSide: 
                        (MathematicOperator)
                            LeftSide: (Field_Reference)    --> EmployeeFields.DateOfBirth
                            RightSide: (constant)    --> 10
                            Operator:      --> -
                    RightSide: (constant)    --> 1.2
                    Operator:     --> ***
            RightSide: (constant)    --> 1024
            Operator:     --> +
    Operator:     --> >

Это вся основа работы таких вещей, как лямбда-выражения и беглый запрос. Все сводится к оценке выражения.

Лямбда-выражения более ... выразительны в том, что они могут касаться объектов, их полей, свойств и методов и позволяют формировать синтаксическое дерево произвольной длины.

...