Finding Reducible Expressions

Posted by on . Last Updated on . Tagged:dotnet

Today I just wanted to share a quick note regarding a Stack Overflow answer that I recently came across. In the answer the author explains that a call to Expression.CanReduce will typically return false, while Expression.Reduce() will return the current expression. The author continues to state that one of the types that overrides Expression.Reduce() and Expression.CanReduce is MemberInitExpression.

I wanted to find out when Expression.CanReduce would actually return true. I discovered the 173 page Expression Tree Specification which provides an additional insight to CanReduce and Reduce().

CanReduce

This property returns whether the Reduce method returns a different but semantically equivalent ET. By default, this property returns false. In the typical case, the resulting ET contains all common ET nodes suitable for passing to any common compilation or ET processing code. Sometimes the result is only partially reduced, and when walking the resulting ET, you’ll need to further reduce some nodes. The value returned by this property should never change for a given object. Here’s the signature:

    public virtual Boolean CanReduce { get; }

Reduce

This method returns a semantically equivalent ET representing the same expression. By default, this method returns the object on which it was invoked. Typically the result comprises only common ET types, ET nodes suitable for passing to any compilation or ET processing code. Usually the result is only partially reduced (that is, only the root node). You’ll probably need to further reduce some nodes. Here’s the signature:

    public virtual Expression Reduce();

Reducible Types Inside System.Linq.Expressions

Using Telerik’s JustDecompile, I went through each public class to see which had an override on either CanReduce or Reduce(). The result came up with the following list:

Furthermore, I searched for descendant types of the list above and found the following reducible classes that were marked as internal, as such I couldn’t find any official documentation for them:

  • AssignBinaryExpression
  • CoalesceConversionBinaryExpression
  • LogicalBinaryExpression
  • SimpleBinaryExpression

Further Reading

Inside the expression tree specification, I would also be inclined to read section 2.2 entitled Reducible Nodes.

If there are any additional expressions that can be reduced that I have missed, please send me a message and I will add it to the list.

Stuart Blackler is a seasoned technologist with over 15 years of commercial experience in the .NET ecosystem. Holding a degree in Computer Science, Stuart has earned certifications as a C# developer through Microsoft and as an AWS Solutions Architect and Developer. Stuart is the creator of the popular YouTube channel CodeWithStu, where he delves into topics close to his heart, including .NET, AWS, DevOps, and software architecture with a commitment to sharing knowledge and fostering a community of learners.