【发布时间】:2012-04-07 21:51:55
【问题描述】:
据我了解,每种语言都可以有自己的dynamic 处理程序,以便应用适当的规则。我不确定以下内容是否正确/不正确;想法?
场景:两个接口(一个实现另一个)和一些方法:
public interface IA {
void Bar(object o);
}
public interface IB : IA {
void Foo(object o);
}
和一个基本的实现:
public class B : IB {
public void Foo(object o) { Console.WriteLine("Foo"); }
public void Bar(object o) { Console.WriteLine("Bar"); }
}
现在,使用普通 C#(没有 dynamic),我们可以从 IB 类型的目标访问 IA 的方法:
IB b = new B();
var o = new { y = "z" };
b.Foo(o.y); // fine
b.Bar(o.y); // fine
现在让我们特意在参数中添加一些dynamic,这使得整个调用使用dynamic 处理(因为在一般情况下这可能会影响重载决议,尽管它不会在这里):
IB b = new B();
dynamic x = new {y = "z"};
b.Foo(x.y); // fine
b.Bar(x.y); // BOOM!
RuntimeBinderException 失败:
“IB”不包含“酒吧”的定义
现在,它所说的完全正确,因为 IB 没有 有 Bar 方法。但是,如第一个示例所示:在正常的 C# 规则下,由于目标的声明类型是接口 (IB),因此已知要实现的其他接口 (即 IA) 会被检查为重载决议。
那么:这是一个错误吗?还是我看错了?
【问题讨论】:
-
+1 有趣。我想知道与编译器/CLR 相比,DLR 是否对这类事情提供较少的支持。我认为 DLR 负责尝试解决呼叫?
-
@Adam 我的理解是,对于基于反射的调用,有一个特定于语言的提供程序,正是为了遵循语言约定,即
Microsoft.CSharp.RuntimeBinder.Binder -
在类继承尝试调用基方法时,您是否观察到相同的情况? (与继承的接口方法相反)。
-
@Adam 是的,这是在描述同一个问题 - 我认为这个问题略有不同;这个问题的目的是:“这种行为是否正确”。我明白发生了什么,只是不知道它是否正确。