问题
I have a generated lambda, but when I want to watch it's like a normal lambda it just doesn't show anything. When I call expr.Body.ToString()
I get following:
{var compareA; ... }
But DebugView for expression works fine:
.Lambda #Lambda1<System.Comparison`1[XLinq.Test.Comparers.CustomComparerTest+Test]>(
XLinq.Test.Comparers.CustomComparerTest+Test $x,
XLinq.Test.Comparers.CustomComparerTest+Test $y) {
.Block(System.Int32 $compareA) {
$compareA = .Call ($x.A).CompareTo($y.A);
.If ($compareA != 0) {
.Return #Label1 { $compareA }
} .Else {
.Block(System.Int32 $compareB) {
$compareB = .Call ($x.B).CompareTo($y.B);
.If ($compareB != 0) {
.Return #Label1 { $compareB }
} .Else {
.Block(System.Int32 $compareC) {
$compareC = .Call ($x.C).CompareTo($y.C);
.If ($compareC != 0) {
.Return #Label1 { $compareC }
} .Else {
.Block(System.Int32 $compareD) {
$compareD = .Call ($x.D).CompareTo($y.D);
.If ($compareD != 0) {
.Return #Label1 { $compareD }
} .Else {
.Default(System.Void)
}
}
}
}
}
}
};
.Label
0
.LabelTarget #Label1:
}
}
Why am I getting this result?
回答1:
This is because the Expression.ToString
override relies on the internal ExpressionStringBuilder
visitor type, which produces a greatly simplified expression tree representation.
The debug view provided by custom debugger proxies defined on each Expression
-derived type (i.e. [DebuggerTypeProxy(typeof(Expression.BlockExpressionProxy))]
on BlockExpression
) provides a lot more information, as you've found out, by exposing the output of a more verbose DebugViewWriter
visitor (also internal).
Unfortunately, you can't get that output easily outside of debug scenarios, unless you're willing to use reflection to fetch the value of a private DebugView
property (defined in System.Linq.Expressions.Expression
) as follows:
Expression<Func<string, int>> expr = str => str.Length;
BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
PropertyInfo debugViewProp = typeof(Expression).GetProperty("DebugView", flags);
MethodInfo debugViewGetter = debugViewProp.GetGetMethod(nonPublic: true);
string debugView = (string)debugViewGetter.Invoke(expr, null);
Produces
.Lambda #Lambda1<System.Func`2[System.String,System.Int32]>(System.String $str) {
$str.Length
}
As always, Reference Source is your best friend:
http://referencesource.microsoft.com/#System.Core/Microsoft/Scripting/Ast/Expression.cs,aa5f054356a8a17d
来源:https://stackoverflow.com/questions/34116591/does-expression-tostring-work