基于接口的方法是否应该调用使用“动态”仍遵循C#方法解析规则?

时间:2012-03-23 10:19:00

标签: c# dynamic

据我了解,每种语言都可以拥有自己的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),我们可以从类型为IA的目标中访问IB的方法:

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'不包含'Bar'的定义

现在,它所说的完全正确,因为IB 没有Bar方法。但是,如第一个示例所示:在正常的C#规则下,由于目标的声明类型是接口(IB),因此已知要实现的其他接口(即IA)是作为重载决议的一部分进行检查。

所以:这是一个错误吗?或者我误读了它?

1 个答案:

答案 0 :(得分:6)

这是粘合剂的众所周知的限制,在SO和this feedback article的主题上被问过几次。我引用微软的回答:

  

由于运送C#4.0的时间,这是我们明确规定的一个领域,我们很乐意重新审视这个问题。在ICollection上实际定义的ISet / IList方法的这种特定情况是最明显的地方,不通过父接口挖掘不必要地限制C#中动态绑定的范围。

     

我们希望尽快增加这样的支持,尽管这个问题目前正在我们的错误分类线下面。我们正在将问题标记为Not not Fix,以表明我们目前尚未跟踪在Visual Studio的下一版本中修复此问题。如果我们通过错误分类列表得到超出预期的,或者如果我们重新审视以下版本的错误,我们将在明年重新激活此错误。

尚未发生,afaik。这篇文章没有很多选票。