Подтвердить что ты не робот

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

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

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>

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

4b9b3361

Ответ 1

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

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

Func<IEnumerable<T>> del = expression.Compile();
IEnumerable<T> value = del();

Ответ 2

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

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

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

var del = expression.Compile();
del();