If an anonymous function Expression<Func<...>> uses variables from outer scope, its expression tree would contain MemberExpression applied to the instance of anonymous class. This instance is presented by ConstantExpression and contains current variable values. The IL code references it as first parameter with OpCodes.Ldarg_0 code. In the same manner, the methods would reference the instance of their class.
The Decompile generates for both cases an expression with $this as first parameter, while for anonymous function $this should be replaced by current instance of function scope class.
The following test fails
[Test]
public void ShouldBeAbleToDecompileObjectInitializerWithOuterVariables()
{
var date = DateTime.Now;
Expression<Func<DateTime, TestClass>> expression = (x) => new TestClass { StartDate = date };
Func<DateTime, TestClass> compiled = (x) => new TestClass { StartDate = date };
Test(expression, compiled);
}
Because the body of expression is
new TestClass() {StartDate = value(DelegateDecompiler.Tests.DecompileExtensionsTests+<>c__DisplayClass37_0).date}
while the body of decompiled expression is
new TestClass() {StartDate = this.date}
I don’t know either this is technically possible to inject in decompiled expression tree the current value of DelegateDecompiler.Tests.DecompileExtensionsTests+<>c__DisplayClass37_0.
If an anonymous function
Expression<Func<...>>
uses variables from outer scope, its expression tree would containMemberExpression
applied to the instance of anonymous class. This instance is presented byConstantExpression
and contains current variable values. The IL code references it as first parameter withOpCodes.Ldarg_0
code. In the same manner, the methods would reference the instance of their class.The
Decompile
generates for both cases an expression with$this
as first parameter, while for anonymous function$this
should be replaced by current instance of function scope class.The following test fails
Because the body of
expression
iswhile the body of decompiled expression is
I don’t know either this is technically possible to inject in decompiled expression tree the current value of
DelegateDecompiler.Tests.DecompileExtensionsTests+<>c__DisplayClass37_0
.Related to #83