在研究C#动态关键字的工作原理时,我偶然发现了一些奇怪的行为。它看起来几乎像是一个bug,但它更可能是有原因的。
在下面的代码中,有两个调用,一个是对obj1的调用,另一个是对obj2的调用,但只有一个调用可以正确执行。似乎局部变量类型是原因,但"Hello“也应该可以从IDynamicTarget访问,因为它扩展了IDynamicTargetBase。
namespace DynamicTesting
{
interface IDynamicTargetBase
{
string Hello(int a);
}
interface IDynamicTarget : IDynamicTargetBase
{
}
class DynamicTarget : IDynamicTarget
{
public string Hello(int a)
{
return "Hello!";
}
}
class Program
{
static void Main(string[] args)
{
dynamic a = 123;
IDynamicTargetBase obj1 = new DynamicTarget();
obj1.Hello(a); // This works just fine
IDynamicTarget obj2 = new DynamicTarget();
obj2.Hello(a); // RuntimeBinderException "No overload for method 'Hello' takes '1' arguments"
}
}
}发布于 2015-01-25 19:45:20
这似乎是一个方法重载解决问题。
只需将dynamic a = 123更改为int a = 123,您的代码就会正常工作。另外,如果您将方法调用更改为obj2.Hello((int)a);。最后,输入变量DynamicTarget而不是IDynamicTarget,它也会起作用!
为什么?当您使用动态表达式,并且有多个方法重载调用具有动态参数时,运行时将无法解析调用哪个重载,因为方法重载解析是基于调用所谓的方法时提供的参数的类型和顺序。
我的猜测是,当一个接口还实现了其他接口时,运行时重载解析将失败,并且运行时似乎理解,不能保证第二个接口将定义也实现的其他接口的重载,并且它迫使您在编译时提供参数的实际类型。
...但是"Hello“也应该可以从IDynamicTarget访问,因为它扩展了IDynamicTargetBase。
它是可访问的,但运行时无法解析如何提供方法的参数...
https://stackoverflow.com/questions/28135176
复制相似问题