Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explain 2 pairs of parentheses in expression.Compile()()

Could you please explain what this strange code does?

expression.Compile()();

Why are there 2 pairs of parentheses here? I didn't find anything in google. The full method is

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;
}

It is used like this:

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

This method checks if a collection is empty or null. Everything works fine but I am a little bit confused with that code. I have never seen using 2 pairs of parentheses before in C#. What does it mean?

like image 805
Marun Gordon Avatar asked Jan 03 '18 13:01

Marun Gordon


2 Answers

Well, you pass list of int into the method as expression tree. This expression produces the value of IEnumerable<T> (in this case IEnumerable<int>).

To get value of expression you need to compile this expression into a delegate Func<IEnumerable<T>> and then invoke the delegate. In fact, I can write two separate lines of code instead of the shorter syntax used above:

Func<IEnumerable<T>> del = expression.Compile();
IEnumerable<T> value = del();
like image 57
Roman Marusyk Avatar answered Nov 19 '22 21:11

Roman Marusyk


The two brackets () is actually an operator which invokes a method or delegate. See here.

The expression "expression.Compile()" seems to deliver a delegate that can be invoked. The second pair of brackets then invokes this delegate.

You could also rewrite this as:

var del = expression.Compile();
del();
like image 4
LosWochos Avatar answered Nov 19 '22 22:11

LosWochos