Kru*_*lur 44 .net c# expression-trees
我正在调用一种接受的方法Expression<Func<bool>>.
作为我传递的表达的一部分:
this.Bottom == base.lineView.Top
Run Code Online (Sandbox Code Playgroud)
编译器给了我一个错误
表达式树可能不包含基本访问权限
所以我只是把它改成了
this.Bottom == this.lineView.Top
Run Code Online (Sandbox Code Playgroud)
因为该成员无论如何都受到保护,现在它起作用了.
但这个错误真的让我:为什么这会base是一个问题呢?特别是如果使用this而不是工作但在语法上是相同的结果(相同的变量被访问)?
Jon*_*eet 43
查看System.Linq.Expressions.Expression文档,我认为没有表示"基本成员访问"的表达式类型.不要忘记,即使在你的情况下它意味着同样的this,在其他情况下它不会:
class Test
{
void Foo()
{
Expression<Func<string>> baseString = () => base.ToString();
}
public override string ToString()
{
return "overridden value";
}
}
Run Code Online (Sandbox Code Playgroud)
这表示对Object.ToString()(for this)的非虚拟调用.我无法看到它将如何在表达式树中表示,因此错误.
现在,这导致了一个显而易见的问题,即为什么在表达式树中没有非虚拟基本成员调用的表示 - 我担心我无法回答那个部分...虽然我可以看到,如果你可以构建这个表达式以编程方式,允许您从外部绕过正常的多态,而不是仅从类本身内部(这是正常情况).这可能是原因.(不可否认,有其他方法可以非虚拟地调用方法,但这是另一回事,我敢说有些情况下表达式树是"可信任的",但其他代码则不然.)
Eri*_*ert 40
乔恩的回答是正确的.我想跟进Jon的评论:
我可以看到,如果你可以以编程方式构建该表达式,那将允许您从外部绕过正常的多态,而不是仅从类本身内部(这是正常情况).这可能是原因
假设你有
public abstract class B // Prevent instantiation
{
internal B() {} // Prevent subclassing outside the assembly.
public virtual void Dangerous() { ... }
}
public sealed class D : B
{
public override void Dangerous()
{
if (!Allowed()) throw whatever;
base.Dangerous();
}
Run Code Online (Sandbox Code Playgroud)
如果没有进行安全检查,那么部分信任的代码就D无法调用B.Dangerous实例.DD.Dangerous
因此,CLR验证程序限制您从类层次结构外部对虚拟方法执行非虚拟调用(基本调用当然是非虚拟调用).事实上,它走得更远; 你甚至不能从嵌套在其中的类中执行它D!(当然,如果您的程序被授予跳过验证的权限,那么您可以做任何您想做的事情;您可以在无法验证的代码中取消引用任意指向内存的指针,这比在虚拟方法上进行静态调用要糟糕得多.)
当我们设计表达式树时,我们不想处理这个混乱的安全问题.最简单的方法就是简单地使整件事变得非法.
表达式树存在许多其他安全问题,这些问题不容易解决,但这些问题是另一天的话题.
| 归档时间: |
|
| 查看次数: |
2140 次 |
| 最近记录: |