Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从继承接口调用方法时,传递动态参数会引发RuntimeBinderException_C#_C# 4.0_Dynamic - Fatal编程技术网

C# 从继承接口调用方法时,传递动态参数会引发RuntimeBinderException

C# 从继承接口调用方法时,传递动态参数会引发RuntimeBinderException,c#,c#-4.0,dynamic,C#,C# 4.0,Dynamic,经过一些重构后,遇到了一个有趣的运行时问题,并将其归结为以下情况 将属性从动态对象传递给从父接口继承的接口上的方法时,运行时绑定器找不到该方法 下面是一个测试,演示了失败和成功(当直接在父接口类型上调用方法时) 测试1失败: Assert.AreEqual失败。预期:。实际:。'Test.Utility.IInheritEcho'不包含“EchoString”的定义 测试2成功 我的问题是,我关于第一次测试应该通过的假设是正确的,还是在框架中有一个根本原因不正确 我知道我可以通过在传入参数时强制

经过一些重构后,遇到了一个有趣的运行时问题,并将其归结为以下情况

将属性从动态对象传递给从父接口继承的接口上的方法时,运行时绑定器找不到该方法

下面是一个测试,演示了失败和成功(当直接在父接口类型上调用方法时)

测试1失败: Assert.AreEqual失败。预期:。实际:。'Test.Utility.IInheritEcho'不包含“EchoString”的定义

测试2成功

我的问题是,我关于第一次测试应该通过的假设是正确的,还是在框架中有一个根本原因不正确

我知道我可以通过在传入参数时强制转换参数或在传入参数之前将参数分配给变量来解决问题。我更好奇的是继承接口导致RuntimeBinder失败的原因…

这是一个好问题

它似乎是在编译时采用表达式的类型,
IInheritEcho
,而不是在寻找动态调用的方法时深入搜索继承接口的成员

理想情况下,
dynamic
表达式的C#runtime binder的行为应该与C#编译器的行为相同-因此它应该看到
IEcho
接口由
IInheritEcho
继承,并且应该可以工作

我们可以通过在第一次测试中这样做来检验假设,即静态类型:

echo = ((dynamic)echomore).EchoString(dynObject.Foo);
嘿,普雷斯托-考试通过了

所以问题不是动态绑定器找不到方法,而是当动态调用其成员的实例被静态类型化为接口时,不会参考继承的接口

我认为这种行为是不正确的


请Eric Lippert。。。友好点…

你的情况是一个记录在案的错误,你完全正确。(虽然它是旧的c版本:)一定是失败了。如果使用具有string属性的常规类而不是expando对象,该怎么办?它在继承的接口中找到方法了吗?(这里没有VS自己做测试)。如果是静态绑定(编译时绑定),那么动态绑定器(运行时绑定器)就有问题。使用带有字符串属性的常规类可以如期通过。这肯定是运行时绑定器不起作用了……如果你看一下igofed与Microsof Connect的答案链接,这个错误是knwon,很可能在新的VS版本中无法解决。所以这是一个已知的问题。下面是关于这个问题的一个很好的讨论。对于任何通过谷歌再次发现这个问题的人来说,微软在2011年4月6日对这个错误的最终判断是“关闭,因为无法修复”,因为它被“确定范围”。嘘:(五年后,它仍然超出了范围?
echo = ((dynamic)echomore).EchoString(dynObject.Foo);