ExpressionTreeToString 3.4.70
See the version list below for details.
dotnet add package ExpressionTreeToString --version 3.4.70
NuGet\Install-Package ExpressionTreeToString -Version 3.4.70
<PackageReference Include="ExpressionTreeToString" Version="3.4.70" />
paket add ExpressionTreeToString --version 3.4.70
#r "nuget: ExpressionTreeToString, 3.4.70"
// Install ExpressionTreeToString as a Cake Addin #addin nuget:?package=ExpressionTreeToString&version=3.4.70 // Install ExpressionTreeToString as a Cake Tool #tool nuget:?package=ExpressionTreeToString&version=3.4.70
Expression Tree To String
Provides a ToString
extension method which returns a string representation of an expression tree (an object inheriting from System.Linq.Expressions.Expression
).
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", "C#"));
// prints:
/*
// using static System.Linq.Expressions.Expression
Lambda(
Constant(true)
)
*/
Console.WriteLine(expr.ToString("Object notation", "C#"));
// 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("Object notation", "Visual Basic"));
// prints:
/*
New Expression(Of Func(Of Boolean)) With {
.NodeType = ExpressionType.Lambda,
.Type = GetType(Func(Of Boolean)),
.Body = New ConstantExpression With {
.Type = GetType(Boolean),
.Value = True
},
.ReturnType = GetType(Boolean)
}
*/
Console.WriteLine(expr.ToString("Textual tree"));
// prints:
/*
Lambda (Func<bool>)
Body - Constant (bool) = True
*/
var b = true;
Expression<Func<int>> expr1 = () => b ? 1 : 0;
Console.WriteLine(expr1.ToString("ToString"));
// prints:
/*
() => IIF(value(_tests.Program+<>c__DisplayClass0_0).b, 1, 0)
*/
Console.WriteLine(expr1.ToString("DebugView"));
// prints:
/*
.Lambda #Lambda1<System.Func`1[System.Int32]>() {
.If (
.Constant<_tests.Program+<>c__DisplayClass0_0>(_tests.Program+<>c__DisplayClass0_0).b
) {
1
} .Else {
0
}
}
*/
Expression<Func<Person, bool>> filter = p => p => p.LastName == "A" || p.FirstName == "B" || p.DOB == DateTime.MinValue || p.LastName == "C" || p.FirstName == "D";
Console.WriteLine(filter.ToString("Dynamic LINQ", "C#"));
// prints:
/*
LastName in ("A", "C") || DOB == DateTime.MinValue || FirstName in ("B", "D")
*/
Features:
Multiple writers:
- 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
- ToString and DebugView reimplementation
- Dynamic LINQ equivalent to the expression
For C# and VB pseudo-code representations:
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
Calls to
String.Concat
andString.Format
are mapped to the+
operator and string interpolation, respectively (where possible):var name = "World"; Expression<Func<string>> expr = () => string.Format("Hello, {0}!", name); Console.WriteLine(expr.ToString("C#")); // prints: () => $"Hello, {name}!"
Unnecessary conversions are not rendered:
Expression<Func<IEnumerable<char>>> expr = () => (IEnumerable<char>)"abcd"; Console.WriteLine(expr.ToString("C#")); // prints: () => "abcd"
Comparisons against an enum or
char
are rendered properly, not as comparison toint
-converted value:var dow = DayOfWeek.Sunday; Expression<Func<bool>> expr = () => DateTime.Today.DayOfWeek == dow; Console.WriteLine(expr.ToString("Textual tree", "C#")); // prints: /* Lambda (Func<bool>) · Body - Equal (bool) = false · Left - Convert (int) = 3 · Operand - MemberAccess (DayOfWeek) DayOfWeek = DayOfWeek.Wednesday · Expression - MemberAccess (DateTime) DateTime.Today = 30/09/2020 12:00:00 am · Right - Convert (int) = 0 · Operand - MemberAccess (DayOfWeek) dow = DayOfWeek.Sunday · Expression - Constant (<closure>) = #<closure> */ Console.WriteLine(expr.ToString("C#")); // prints: () => DateTime.Today.DayOfWeek == dow
Each representation (including the ToString and DebugView renderers) can return the start and length of the substring corresponding to any of the paths of the tree's nodes, which can be used to find the substring corresponding to a given node in the tree:
var s = expr.ToString("C#", out var pathSpans); Console.WriteLine(s); // prints: (Person p) => p.DOB.DayOfWeek == DayOfWeek.Tuesday (int start, int length) = pathSpans["Body.Left.Operand"]; Console.WriteLine(s.Substring(start, length)); // prints: p.DOB.DayOfWeek
Type names are rendered using language syntax and keywords, instead of the Type.Name property; e.g.
List<string>
orList(Of Date)
instead ofList`1
Supports the full range of types in
System.Linq.Expressions
, including .NET 4 expression types, andDynamicExpression
- Expression (and derived types)
- ElementInit
- MemberBinding (and derived types)
- SwitchCase
- CatchBlock
- LabelTarget
Extensibility -- allows creating custom renderers, or inheriting from existing renderers, to handle your own Expression-derived types
For more information, see the wiki.
Feedback
- Star the project
- File an issue
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 is compatible. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net452 is compatible. net46 was computed. net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.5.2
- Microsoft.CSharp (>= 4.7.0)
- ZSpitz.Util (>= 0.1.113)
-
.NETStandard 2.0
- Microsoft.CSharp (>= 4.7.0)
- ZSpitz.Util (>= 0.1.113)
-
net5.0
- Microsoft.CSharp (>= 4.7.0)
- ZSpitz.Util (>= 0.1.113)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on ExpressionTreeToString:
Package | Downloads |
---|---|
RaaLabs.Edge
Package Description |
|
NCPC.Utils
Usefull methods of common use |
|
ExpressionTreeVisualizer.UI
UI pieces for displaying expression trees |
|
NiuX.Common
csharp common, utils, helpers, tools etc. |
|
GCore.Logging.Expressions
Useful C# Stuff for .NET Standard 2.0 |
GitHub repositories (3)
Showing the top 3 popular GitHub repositories that depend on ExpressionTreeToString:
Repository | Stars |
---|---|
yangzhongke/NETBookMaterials
|
|
zspitz/ExpressionTreeVisualizer
Debugging visualizer for expression trees
|
|
NeVeSpl/RevitDBExplorer
Interactive Revit database exploration tool to view and edit BIM element parameters, properties and relationships.
|
Version | Downloads | Last updated |
---|---|---|
3.4.71 | 196,697 | 2/25/2022 |
3.4.70 | 4,063 | 12/23/2021 |
3.4.68 | 1,063 | 12/14/2021 |
3.4.67 | 311 | 12/14/2021 |
3.4.65 | 23,764 | 7/14/2021 |
3.4.64 | 381 | 7/14/2021 |
3.4.63 | 17,924 | 7/5/2021 |
3.4.62 | 644 | 6/29/2021 |
3.4.61 | 576 | 6/23/2021 |
3.4.60 | 389 | 6/23/2021 |
3.3.59 | 427 | 6/17/2021 |
3.3.58 | 489 | 6/7/2021 |
3.3.57 | 387 | 6/6/2021 |
3.3.56 | 445 | 5/31/2021 |
3.2.54 | 42,285 | 1/16/2021 |
3.2.53 | 6,842 | 12/6/2020 |
3.2.52 | 550 | 12/5/2020 |
3.2.51 | 551 | 12/5/2020 |
3.2.50 | 539 | 12/5/2020 |
3.2.49 | 434 | 12/5/2020 |
3.2.48 | 2,210 | 10/28/2020 |
3.1.47 | 502 | 10/8/2020 |
3.1.45 | 737 | 9/30/2020 |
3.1.44 | 552 | 9/30/2020 |
3.1.43 | 484 | 9/24/2020 |
3.1.42 | 506 | 9/23/2020 |
3.0.41 | 618 | 9/16/2020 |
2.2.40 | 497 | 9/15/2020 |
2.2.39 | 482 | 9/15/2020 |
2.2.38 | 468 | 9/14/2020 |
2.2.37 | 567 | 8/31/2020 |
2.2.36 | 485 | 8/26/2020 |
2.1.34 | 504 | 8/24/2020 |
2.1.33 | 432 | 8/24/2020 |
2.0.32 | 536 | 8/18/2020 |
2.0.29 | 918 | 8/5/2020 |
2.0.28 | 529 | 7/19/2020 |
2.0.27 | 4,460 | 7/19/2020 |
2.0.26 | 579 | 7/19/2020 |
2.0.25 | 480 | 7/16/2020 |
2.0.23 | 558 | 6/28/2020 |
2.0.22 | 579 | 6/27/2020 |
2.0.21 | 562 | 6/27/2020 |
2.0.20 | 6,130 | 3/29/2020 |
2.0.19 | 616 | 3/29/2020 |
2.0.15 | 756 | 12/18/2019 |
2.0.14 | 550 | 12/18/2019 |
2.0.13 | 547 | 12/18/2019 |
2.0.12 | 520 | 12/18/2019 |
2.0.11 | 526 | 12/18/2019 |
2.0.10 | 573 | 12/16/2019 |
2.0.4 | 523 | 12/15/2019 |
1.6.2 | 566 | 12/15/2019 |
1.5.67 | 2,866 | 8/15/2019 |
1.5.66 | 661 | 8/14/2019 |
1.5.65 | 690 | 8/13/2019 |
1.4.64 | 683 | 8/1/2019 |
1.4.63 | 678 | 7/4/2019 |
1.4.62 | 660 | 7/4/2019 |
1.4.57 | 643 | 6/26/2019 |
1.3.55 | 670 | 6/25/2019 |
1.3.54 | 663 | 6/25/2019 |
1.3.53 | 641 | 6/24/2019 |
1.3.52 | 677 | 6/23/2019 |
1.3.51 | 666 | 6/21/2019 |
1.3.50 | 691 | 6/21/2019 |
1.3.49 | 676 | 6/21/2019 |
1.3.41 | 654 | 6/20/2019 |
1.3.35 | 659 | 6/18/2019 |
1.3.34 | 692 | 5/30/2019 |
1.3.33 | 678 | 5/30/2019 |
1.2.32 | 681 | 5/30/2019 |
1.2.30 | 695 | 5/30/2019 |
1.2.29 | 652 | 5/29/2019 |
1.2.28 | 711 | 5/21/2019 |
1.2.27 | 693 | 5/14/2019 |
1.2.19 | 3,806 | 5/3/2019 |
1.1.10 | 711 | 3/24/2019 |
1.1.7 | 706 | 3/15/2019 |
1.1.6 | 677 | 3/14/2019 |
1.1.5 | 659 | 3/14/2019 |
1.0.1 | 779 | 2/17/2019 |
1.0.0 | 791 | 2/14/2019 |
Non-statement expression support is complete, escaped string literals, exceptions written into source