【发布时间】:2018-07-09 07:57:42
【问题描述】:
在以下代码示例中,调用 l.Add(s) 和 c.Add(s) 成功,但调用通用 IList<string> 时失败。
var l = new List<string>();
dynamic s = "s";
l.Add(s);
var c = (ICollection<string>)l;
c.Add(s);
var i = (IList<string>)l;
i.Add("s"); // works
i.Add(s); // fails
https://dotnetfiddle.net/Xll2If
未处理的异常:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:方法“Add”没有重载需要“1”个参数 在 CallSite.Target(闭包,CallSite,IList`1,对象) 在 System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite 站点,T0 arg0,T1 arg1) 在 C:\Dev\PlayGround\PlayGround\Program.cs:line 13 中的 Program.Main() 处
IList<T> 派生自 ICollection<T>。有人可以解释为什么IList.Add 的调用失败了吗?
【问题讨论】:
-
真的很奇怪。很好的发现。
i的类型是IList<dynamic>,不是dynamic,所以看起来i.Add调用应该在编译时绑定(绑定)。它编译。然而,在运行时,绑定似乎失败了?!对我来说这似乎是一个错误! -
显然绑定被推迟到运行时,因为参数
s的类型是dynamic。如果您将s更改为var s = "s";,则不会出现该错误。无论如何,有趣的是为什么c.Add运行良好,而i.Add却不行。 -
顺便说一句,
dynamic在这里不相关,它与List<string>相同:"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'No 方法的重载'Add ' 接受 '1' 个参数'" 我猜是因为IList<T>is a readonly interface. -
@JeppeStigNielsen 我已经想通了。我只是想关注显示奇怪行为的最小可能示例。
-
@hvd 这正是它所做的,也正是在 corefx 中修复所必需的。还需要在查找末尾显式添加
object。