Consider the following Expression:
class A {
    int x;
    public void Method(int y) {
        Expression<Func<bool>> expr=() => x == y;
        //...
Here, the expression involves an automatically created closure for y, and a reference to this of type A for the (implicit) this.x.  Both will be represented as a MemberExpression on a ConstantExpression in the expression tree.  Given an expression such as expr or a more complicated expression with a this reference and/or a closure, I want identify that a particular ConstantExpression is actually "this" or an implicitly constructed closure to be able to regenerate C# from an expression tree (ExpressionToCode).
I built a "solution" using some heuristics since there doesn't seem to be a perfect solution.
this in lambda's are always in ConstantExpressions.this are never null.this from a struct.  That's quite fortunate, because telling default(StructType).Method() from this.Method() would otherwise be impossible whenever this == default(StructType).this or a closure< and are annotated with CompilerGeneratedAttribute
DisplayClass, anonymous types contain AnonymousType
this must 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? I.e. are there cases where these heuristics fail, or am I missing any?  Is this likely to break in future .NET versions?
Edit: I first asked this question in an open-ended fashion, without result; I rewrote the question to include what I've come up so far. Any suggestions much appreciated - the bounty's expiring tomorrow, any idea at all is welcome...
Ok, I manage to find about the A Type from the expression:
class Program
{
    class A
    {
        int x;
        public Expression<Func<bool>> Method(int y)
        {
            Expression<Func<bool>> expr = () => x == y;
            return expr;
        }
    }
    static void Main(string[] args)
    {
        var expr = new A().Method(10);
        dynamic body = expr.Body;
        A instance = body.Left.Expression.Value;
        Console.Write(instance.ToString());
        Console.ReadKey();
    }
 }
The dynamic is just to go fast.
edit 2: got it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With