This project provides the following:
- Extension methods to create a C# or VB.NET code-like string representation, of expression trees or expression tree parts (.NET Standard library)
- A debugging visualizer for expression trees / expression tree parts
Installation: The visualizer DLL (2019 or 2017, depending on your VS version) and the dependent DLL (MultiSelectTreeView.DLL
), from the releases page, should be placed in the appropriate folder, as described here. It may be necessary to unblock the DLLs, and/or to put them in anetstandard2.0
subfolder.
- Star the project
- File an issue
Expression<Func<bool>> expr = () => true;
Console.WriteLine(expr.ToString("C#"));
// prints: () => true
Console.WriteLine(expr.ToString("Visual Basic"));
// prints: Function() True
Console.WriteLine(expr.ToString("Factory methods"));
// prints:
/*
// using static System.Linq.Expressions.Expression
Lambda(
Constant(true)
)
*/
Console.WriteLine(expr.ToString("Object notation"));
// prints:
/*
new Expression<Func<bool>> {
NodeType = ExpressionType.Lambda,
Type = typeof(Func<bool>),
Body = new ConstantExpression {
Type = typeof(bool),
Value = true
},
ReturnType = typeof(bool)
}
*/
Console.WriteLine(expr.ToString("Textual tree"));
// prints:
/*
Lambda (Func<bool>)
Body - Constant (bool) = True
*/
Features:
-
Multiple formatters (with more planned):
- Pseudo-code in C# or VB.NET
- Factory method calls which generate this expression
- Object notation, using object initializer and collection initializer syntax to describe objects
- Textual tree, focusing on the properties related to the structure of the tree
-
Extension methods are rendered as instance methods
Expression<Func<int, int>> expr = x => Enumerable.Range(1, x).Select(y => x * y).Count(); Console.WriteLine(expr.ToString("C#")); // prints: (int x) => Enumerable.Range(1, x).Select((int y) => x * y).Count()
-
Closed-over variables are rendered as simple identifiers (instead of member access on the hidden compiler-generated class)
var i = 7; var j = 8; Expression<Func<int>> expr = () => i + j; Console.WriteLine(expr.ToString("C#")); // prints: () => i + j
-
Type names are rendered using language keywords, instead of just the type name; e.g.
List<string>
orList(Of Date)
instead ofList`1
-
Special handling of calls to
String.Concat
andString.Format
var name = "World"; Expression<Func<string>> expr = () => string.Format("Hello, {0}!", name); Console.WriteLine(expr.ToString("C#")); // prints: () => $"Hello, {name}!"
-
Supports the full range of types in
System.Linq.Expressions
, including .NET 4 expression types, andDynamicExpression
The UI consists of:
- a graphical treeview of the expression tree structure,
- source code representation of the tree, and
- end nodes -- nodes in the tree which are not composed of other expressions: parameters, closure variables, constants and default values
You can switch formatters without reloading the visualizer:
Selection syncing:
- John M. Wright's series on writing debugger visualizers
- Multiple-selection treeview is provided by MultiSelectTreeView
- ReadableExpressions
- Greenshot and ScreenToGIF for the screenshots