Consider the following expression:
class A { int x; public void Method(int y) { Expression<Func<bool>> expr=() => x == y;
Here, the expression includes an automatically generated closure for y and a reference to this type A for the (implicit) this.x Both will be represented as MemberExpression in ConstantExpression in the expression tree. Given an expression such as expr or a more complex expression with this link and / or closure, I want to determine that a particular ConstantExpression is actually "this" or an implicitly configured closure to be able to regenerate C # from the expression tree ( ExpressionToCode ).
I built a βsolutionβ using some heuristics, as it does not seem to be an ideal solution.
- Closures and
this in lambda are always in ConstantExpressions . - Closures and
this never null . - Both are classes, not value types - you cannot write a reference to
this from the structure. This is pretty good, because saying default(StructType).Method() from this.Method() would otherwise be impossible whenever this == default(StructType) . - The built-in types (string, Enums, decimal, Type, all primitives) are actually real constants, not
this or closing - Closures and anonymous types begin with
< and are annotated using CompilerGeneratedAttribute- Closing names contain a string
DisplayClass , anonymous types contain AnonymousType - Anonymous types are common; closure is not.
- Closing is nested classes, anonymous types are not.
this should be a normal type: not CompilerGenerated and does not start with <
Are the above heuristics sufficient to distinguish between real constants, this , closures, and anonymous types? That is, are there cases where these heuristics fail, or do I miss them? Is it possible that this will happen in future versions of .NET?
Edit: I first asked this question in an open way, with no result; I rewrote the question to include what I have found so far. Any suggestions that were highly appreciated - tomorrow's breakfast, any idea is generally welcome ...
Eamon nerbonne
source share