Skip to content

Available renderers

Zev Spitz edited this page Aug 19, 2020 · 15 revisions

There are currently 5 available renderers, which can be referred to either by a string or an enum value from BuiltinRenderer.

1. C#-style pseudo-code

  • String: "C#"
  • Enum: BuiltinRenderer.CSharp
Console.WriteLine(expr.ToString("C#"));
/*
    (Person p) => p.DOB.DayOfWeek == DayOfWeek.Tuesday
*/

2. Visual Basic-style pseudocode

  • String: "Visual Basic"
  • Enum: BuiltinRenderer.VisualBasic
Console.WriteLine(expr.ToString("Visual Basic"));
/*
    Function(p As Person) p.DOB.DayOfWeek = DayOfWeek.Tuesday
*/

3. Factory methods

The factory method calls used to generate the expression, or one very much like it:

  • String: "Factory methods"
  • Enum: BuiltinRenderer.FactoryMethods
Console.WriteLine(expr.ToString("Factory methods"));
/*
    // using static System.Linq.Expressions.Expression

    Lambda(
        Equal(
            Convert(
                MakeMemberAccess(
                    MakeMemberAccess(p,
                        typeof(Person).GetProperty("DOB")
                    ),
                    typeof(DateTime).GetProperty("DayOfWeek")
                ),
                typeof(int)
            ),
            Constant(2)
        ),
        var p = Parameter(
            typeof(Person),
            "p"
        )
    )
*/

Note When generating an expression tree that contains a ParameterExpression instance, you need to reuse the same parameter object across the entire expression tree. Therefore, we use a non-syntactical inline variable declaration (var p = ...) to represent the first use of a ParaneterExpression.

Ideally this declaration is a separate statement, and should be before the first function call; this is tracked in https://github.com/zspitz/ExpressionTreeToString/issues/8.

4 . Object notation

Describes objects and collections using initializer syntax:

  • String: "Object notation"
  • Enum: BuiltinRenderer.ObjectNotation
Console.WriteLine(expr.ToString("Object notation"));
/*
    new Expression<Func<Person, bool>> {
        NodeType = ExpressionType.Lambda,
        Type = typeof(Func<Person, bool>),
        Parameters = new ReadOnlyCollection<ParameterExpression> {
            new ParameterExpression {
                Type = typeof(Person),
                IsByRef = false,
                Name = "p"
            }
        },
        Body = new BinaryExpression {
            NodeType = ExpressionType.Equal,
            Type = typeof(bool),
            Left = new UnaryExpression {
                NodeType = ExpressionType.Convert,
                Type = typeof(int),
                Operand = new MemberExpression {
                    Type = typeof(DayOfWeek),
                    Expression = new MemberExpression {
                        Type = typeof(DateTime),
                        Expression = new ParameterExpression {
                            Type = typeof(Person),
                            IsByRef = false,
                            Name = "p"
                        },
                        Member = typeof(Person).GetProperty("DOB")
                    },
                    Member = typeof(DateTime).GetProperty("DayOfWeek")
                }
            },
            Right = new ConstantExpression {
                Type = typeof(int),
                Value = 2
            }
        },
        ReturnType = typeof(bool)
    }
*/

5. Textual tree

Describes the structure of the expression tree: node type, reflection type, name and value, as appropriate

  • String: "Textual tree"

  • Enum: BuiltinRenderer.TextualTree

    Console.WriteLine(expr.ToString("Textual tree"));
    /*
      Lambda (Func<Person, bool>)
          Parameters[0] - Parameter (Person) p
          Body - Equal (bool)
              Left - Convert (int)
                  Operand - MemberAccess (DayOfWeek) DayOfWeek
                      Expression - MemberAccess (DateTime) DOB
                          Expression - Parameter (Person) p
              Right - Constant (int) = 2
    */