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

据我所知,每种语言都有自己的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(oy); // fine b.Bar(oy); // fine 

现在让我们故意在参数中添加一些dynamic ,这使得整个调用使用dynamic处理(如在一般情况下,这可能会影响重载解析,尽管它不会在这里):

 IB b = new B(); dynamic x = new {y = "z"}; b.Foo(xy); // fine b.Bar(xy); // BOOM! 

哪个失败了RuntimeBinderException

‘IB’不包含’Bar’的定义

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

那么:这是一个错误吗? 还是我误读了?

这是粘合剂的众所周知的限制,在SO和本反馈文章的主题上被问过几次。 我引用微软的答案:

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

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

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