Объясните две пары круглых скобок в expression.Compile () ()

18

Не могли бы вы объяснить, что делает этот странный код?

expression.Compile()();

Почему здесь две пары круглых скобок? Я не нашел ничего в google. Полный метод

public Validator NotEmpty(Expression<Func<IEnumerable<T>>> expression)
{
    var member = (MemberExpression)expression.Body;
    string propertyName = member.Member.Name;
    IEnumerable<T> value = expression.Compile()();

    if (value == null || !value.Any())
    {
        ValidationResult.AddError(propertyName, "Shouldn't be empty");
    }
    return this;
}

Он используется следующим образом:

_validator.NotEmpty(() => request.PersonIds);  // request.PersonIds is List<int>

Этот метод проверяет, является ли коллекция пустой или пустой. Все работает нормально, но я немного смущен этим кодом. Я никогда не видел использование двух пар круглых скобок раньше в C #. Что это значит?

    
задан Marun Gordon 03.01.2018 в 14:07
источник
  • , который вызывает скомпилированное выражение Func <IEnumerable <T >>. –  Nkosi 03.01.2018 в 14:09
  • FYI: вторая пара () является сокращением для .Invoke (); Таким образом, строка эквивалентна: expression.Compile (). Invoke (); –  Dennis_E 03.01.2018 в 14:16

2 ответа

25

Ну, вы передаете список int в метод как дерево выражений. Это выражение выражает значение IEnumerable<T> (в данном случае IEnumerable<int> ).

Чтобы получить значение выражения, вам нужно скомпилировать это выражение в делегат Func<IEnumerable<T>> , а затем вызвать делегата. На самом деле, я могу написать две отдельные строки кода вместо более короткого синтаксиса, описанного выше:

Func<IEnumerable<T>> del = expression.Compile();
IEnumerable<T> value = del();
    
ответ дан Roman Marusyk 03.01.2018 в 14:09
источник
4

Два скобки () - фактически оператор, который вызывает метод или делегат. См. здесь .

Выражение «выражение.Compile ()», кажется, предоставляет делегат, который может быть вызван. Вторая пара скобок вызывает этот делегат.

Вы также можете переписать это как:

var del = expression.Compile();
del();
    
ответ дан LosWochos 03.01.2018 в 14:16
источник