如果基于接口的方法调用使用“;动态的“;仍然遵守C#方法解析规则

本文关键字:方法 动态 规则 于接口 接口 调用 如果 | 更新日期: 2023-09-27 18:28:59

据我所知,每种语言都可以有自己的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),作为过载解决的一部分。

那么:这是一个bug吗?还是我看错了?

如果基于接口的方法调用使用“;动态的“;仍然遵守C#方法解析规则

这是活页夹的一个众所周知的限制,在SO和这篇反馈文章的主题中被问了好几次。我引用微软的答案:

这是我们在发布C#4.0时明确确定的范围,我们很乐意重新审视这一点。实际在ICollection上定义的ISet/IList方法的这种特定情况是最明显的地方,在这种情况下,不通过父接口进行挖掘不必要地限制了C#中动态绑定的范围。

我们希望很快添加这样的支持,尽管这个问题目前刚好低于我们的错误分类截止线。我们将此问题标记为"不会修复",表示我们当前没有跟踪以在Visual Studio的下一版本中修复此问题。如果我们的错误分类列表比预期的要深入,或者如果我们在下一个版本中重新访问该错误,我们将在明年重新激活该错误。

这还没有发生,阿法伊克。这篇文章没有太多选票。

相关文章: