.net 启发性;这";那好吗?(表达树)

.net 启发性;这";那好吗?(表达树),.net,linq,expression-trees,.net,Linq,Expression Trees,考虑以下表达式: class A { int x; public void Method(int y) { Expression<Func<bool>> expr=() => x == y; //... class Program { class A { int x; public Expression<Func<bool>> Method(in

考虑以下表达式:

class A {
    int x;
    public void Method(int y) {
        Expression<Func<bool>> expr=() => x == y;
        //...
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();
    }
 }
A类{
int x;
公共无效方法(int y){
表达式expr=()=>x==y;
//...
这里,表达式涉及为
y
自动创建的闭包,以及对
a类型的
this
的引用(隐式)
this.x
。两者都将在表达式树中的
ConstantExpression
上表示为
MemberExpression
。给定一个表达式,例如
expr
,或者一个更复杂的表达式,带有this引用和/或闭包,我想确定一个特定的
ConstantExpression
实际上是“this”或隐式构造的闭包
,以便能够从表达式树()中重新生成C

我使用一些启发式方法构建了一个“解决方案”,因为似乎没有一个完美的解决方案

  • lambda中的闭包和
    始终处于
    恒定压力中
  • 闭包和
    this
    永远不会
    null
  • 这两种类型都是类,而不是值类型-您无法从结构中捕获对
    this
    的引用。这是非常幸运的,因为无论何时
    this==default(StructType)
    告诉
    this.Method()
    ,都是不可能的
  • 内置类型(string、Enum、decimal、Type、all primitives)实际上是实常量,而不是
    this
    或闭包

  • 闭包和匿名类型以
    开始好的,我设法从表达式中找到关于A类型的信息:

    class A {
        int x;
        public void Method(int y) {
            Expression<Func<bool>> expr=() => x == y;
            //...
    
    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();
        }
     }
    
    类程序
    {
    甲级
    {
    int x;
    公共表达式方法(int-y)
    {
    表达式expr=()=>x==y;
    返回表达式;
    }
    }
    静态void Main(字符串[]参数)
    {
    var expr=新的A()方法(10);
    动态体=扩展体;
    实例=body.Left.Expression.Value;
    Write(instance.ToString());
    Console.ReadKey();
    }
    }
    
    动力就是快速前进


    编辑2:明白了

    你确定你的假设是正确的吗?在我看来(我不是专家;)),表达式中的x可能只是一个int的“引用”,而不知道a(并且无法从表达式中找到a)好吧,我错了,表达式树可能是这样的(很明显^^)我确信有可能接近答案。我不确定这是否可能-我已经添加了我目前对这一问题的想法,即您需要检测并区分编译器生成的类型、实常量和用户类型-请注意,编译器还生成不适用于闭包的匿名类型属性,闭包使用字段:无论如何,这可能是区分这两者的一条途径。在这个精确的示例中,您在这里所做的工作是有效的,但一般来说不起作用。我将问题的相关部分加粗,因为这是一个任意表达式,并添加了一个澄清点,说明这可能是ac的原因和方式hieved-感谢您的关注!恐怕您想做的是不可能的,从表达式的角度来看,“隐式”闭包和“显式”闭包之间没有区别…什么意思-显式闭包?闭包总是隐式的;而且它们生成的类名称中包含
    DisplayClass
    ,至少这是一部分到目前为止,我使用的是启发式的。我认为带有“this”的闭包与带有任何其他局部对象的闭包相对。啊,好吧,闭包实际上是作为独立对象实现的
    this
    。因此局部变量等被提升到闭包对象,但类变量只是使用
    this
    引用这并不是说
    这个
    是闭包的一个字段或属性,而只是
    ConstantPression
    中的一个独立对象。这也是闭包嵌套的原因:它们需要能够访问周围类的私有成员。