在C#中的错误:"一个前pression树不能包含一个基本访问" - 为什么不呢?错误、基本、QUOT、pression

2023-09-03 08:50:31 作者:aholic(沉迷者)

我在呼唤一个接受的方法防爆pression< Func键<布尔>>

I was calling a method that accepts Expression<Func<bool>>.

由于前pression我是路过的一部分:

As part of the expression I was passing:

this.Bottom == base.lineView.Top

编译器给了我一个错误,

The compiler gave me an error that

这是前pression树不能包含一个基本访问

an expression tree may not contain a base access

所以,我干脆改成了

this.Bottom == this.lineView.Top

因为成员是无论如何保护,现在的作品。

because the member was protected anyway and now it works.

但这个错误真的让我:别人为什么非得将这个基础是一个问题?特别是如果使用,而不是将工作,但在语法上是相同的结果(相同的变量被访问)?

But this error really got me: why the heck would this base be a problem? Especially if using this instead will work but syntactically be the same result (same variable gets accessed)?

推荐答案

纵观System.Linq.Ex$p$pssions.Ex$p$pssion文档,我不认为有一个前pression从而重新presents基地成员访问类型。不要忘记,即使在你的情况下,它的意思相同,只是,在其他情况下,它不会:

Looking at the System.Linq.Expressions.Expression documentation, I don't think there's an expression type which represents "base member access". Don't forget that even though in your case it meant the same as just this, in other cases it wouldn't:

class Test
{
    void Foo()
    {
        Expression<Func<string>> baseString = () => base.ToString();
    }

    public override string ToString()
    {
        return "overridden value";
    }
}

下面,将重新present到 Object.ToString非虚拟呼叫()(对于)。我看不出这将是重新psented在离pression树$ P $,因此错误。

Here that would represent a non-virtual call to Object.ToString() (for this). I can't see how that would be represented in an expression tree, hence the error.

现在,导致上的明显的问题的为什么的没有在EX pression树非虚基成员调用重新presentation - 我怕我不能回答这个问题的一部分......虽然我可以看到,如果你的可以的构建EX pression编程,这将让你从外面绕过正常的多态性的 而不是只从类本身(这是一般的情况)的内部。这可能是这个原因。 (诚​​然有方法调用非虚拟的其他方式,但是这是一个不同的事情,而且我敢说在有些情况下EX pression树是值得信赖的,但其他的code不是。)

Now that leads on to the obvious question of why there isn't a representation of non-virtual base member invocation in expression trees - I'm afraid I can't answer that part... although I can see that if you could build that expression programmatically, that would allow you to bypass normal polymorphism from the outside instead of only from inside the class itself (which is the normal case). That may be the reason. (Admittedly there are other ways of calling methods non-virtually, but that's a different matter, and I dare say there are situations where expression trees are "trusted" but other code isn't.)