What's the story with ExpressionType.Assign?

c# expression-trees lambda linq


I was under the impression that assignment was not possible inside a lambda expression. E.g., the following (admittedly not very useful) code

Expression<Action<int, int>> expr = (x, y) => y = x;

Produces the compiler error

An expression tree may not contain an assignment operator

And yet, according to Microsoft's documentation, one can programmatically create an assignment expression using Expression.Assign. Unless I am mistaken, the following code produces an equivalent Expression:

ParameterExpression xparam = Expression.Parameter(typeof(int), "x");
ParameterExpression yparam = Expression.Parameter(typeof(int), "y");
BinaryExpression body = Expression.Assign(yparam, xparam);
var expr = Expression.Lambda<Action<int, int>>(body, xparam, yparam);
var cexpr = expr.Compile();

In this case, the compiler does not complain. I feel like I am missing some important distinction here.

Accepted Answer

usr's answer is correct; to expand on it somewhat:

You are not missing an important distinction, you are missing an important dimension: time.

If you look at the documentation carefully you'll note that the Assign node was added in .NET 4.0.

Expression trees were added to C# 3.0, which shipped with .NET 3.5.

The team that owns the expression tree library has added many features to it since .NET 3.5 shipped. Using those features to allow more expressions to be in an expression tree in the C# language did not make the cut for C# 4.0 or C# 5.0. There's no reason to not do the feature; it's a perfectly sensible feature. But the language designers do not require a reason to not do a feature; they require a reason to spend the budget on a feature.

In this case, richer expression trees in C# simply did not make it high enough on the priority list. If you'd like that feature to be higher priority then you can open an issue on connect.microsoft.com and request it. Your request is more likely to be implemented if you include a compelling scenario for the feature.

Popular Answer

You are not misunderstanding anything. C# is intentionally restrictive in the kinds of expression trees it can generate for you. There's no principled reason why it couldn't have that feature. It just wasn't invested in. (Creating features takes away resources. Would you rather have async/await or expression tree statements? Clearly the first option is more useful.).

You also cannot generate other statements like if or while although they are in the expression tree API starting with .NET 4. (You can construct and compile complex control flows with expression trees now).

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why