在下面的代码示例中调用l.Add(s)
and 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 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 中的 Program.Main() 处:第 13 行
IList<T>
源自于ICollection<T>
。有人可以解释为什么呼吁IList.Add
fails?
在查找绑定调用的方法时,编译器(无论是静态还是动态)可能必须检查基类型。
一般使用dynamic
我们正在处理对方法的调用dynamic
对象本身,因此动态编译器从正在使用的对象的具体类型开始dynamic
并且只需要沿着它的继承链向上直到到达object
寻找他们。
如果一个dynamic
对象作为参数传递给静态引用为接口类型的方法调用,遗憾的是动态绑定器做了同样的事情:如果它没有找到相关类型的方法,那么它就会查看BaseType
该类型,对于接口来说是null
。因此,它的行为与正确检查继承但未能找到有问题的方法并针对该情况抛出适当的异常时的行为相同。 (请注意,这也意味着它将无法找到Equals
方法定义于object
).
What it should对于这种情况,要做的就是检查相关接口类型实现的所有接口。
这个错误是.NET Core 中已修复 https://github.com/dotnet/corefx/pull/22301但该修复尚未移植到 .NET Framework。如果您想针对 netfx 提交错误报告,您可能需要参考 corefx 中的修复。
有时可以通过定义所用方法的基接口访问接口类型本身,或者将其本身作为接口类型来解决此问题dynamic
(因此可以在实现它的具体类型中找到适当的方法)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)