在下面的代码示例调用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
Run Code Online (Sandbox Code Playgroud)
https://dotnetfiddle.net/Xll2If
未处理的异常:Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:方法'Add'的重载在System.Dynamic.Uynamic.UpdateDelegates.UpdateAndExecuteVoid2 [T0,T1]的CallSite.Target(Closure,CallSite,IList`1,Object)中取'1'参数](CallSite网站,T0 arg0,T1 arg1)位于C:\ Dev\PlayGround\PlayGround\Program.cs中的Program.Main():第13行
IList<T>来源于ICollection<T>.有人可以解释为什么呼叫IList.Add失败?
在查找绑定调用的方法时,编译器(无论是静态还是动态)可能必须检查基类型。
一般来说,dynamic我们处理的是对对象本身方法的调用dynamic,因此动态编译器从正在使用的对象的具体类型开始dynamic,只需要沿着它的继承链向上查找,直到找到object它们。
在将dynamic对象作为参数传递给静态引用为接口类型的方法调用的情况下,动态绑定器可悲地执行相同的操作:如果它没有找到相关类型的方法,那么它会查找在BaseType该类型的 处,对于接口来说是null。因此,它的行为与正确检查继承但未能找到有问题的方法并针对该情况抛出适当的异常时的行为相同。(请注意,这也意味着它将无法找到Equals上定义的方法object)。
对于这种情况,它应该做的是检查相关接口类型实现的所有接口。
此错误已在 .NET Core 中修复,但该修复尚未移植到 .NET Framework 中。如果您想针对 netfx 提交错误报告,您可能需要参考 corefx 中的修复。
有时可以通过定义所使用的方法的基接口访问接口类型本身,或者访问接口类型本身dynamic(因此可以在实现它的具体类型中找到适当的方法)来解决此问题。
| 归档时间: |
|
| 查看次数: |
336 次 |
| 最近记录: |