2015-07-13 40 views
2

为什么我不能重载方法使用dynamicobject参数。动态和其他类型的过载方法

void Method(dynamic arg) // Member with same signature is already declared 
{ 
    Console.WriteLine("Dynamic"); 
} 
void Method(object arg) // Member with same signature is already declared 
{ 
    Console.WriteLine("Not Dynamic"); 
} 

但我可以与dynamic和另一种类型的重载方法除了对象或动态它自己。

void Method(dynamic arg) 
{ 
    Console.WriteLine("Dynamic"); 
} 
void Method(string arg) 
{ 
    Console.WriteLine("Not Dynamic"); 
} 

正如你在第一个例子中看到的,编译器不能区分两个重载。

我想第二个例子不应该工作太多,因为字符串可以发送到两个重载。不过编译器更喜欢用已知类型调用过载。

我已经做了一些测试,看看它是如何工作的。

Method("");   // Prints: Not Dynamic 
Method((dynamic)""); // Prints: Not Dynamic 
Method(null);  // Prints: Not Dynamic 
Method(???);   // Dynamic for any other type except string and null. 

首先考虑例如工作和编译器会决定这样的:

Method(new object());// Prints: Not Dynamic 
Method((object)5); // Prints: Not Dynamic 
Method(???);   // Prints: Dynamic for any other type except object and null. 

那么,是混乱的编译器?为什么我不能有这样的重载?

+2

默认的动态类型是'object'。 ([MSDN](https://msdn.microsoft.com/en-us/library/dd264736.aspx)) – adatapost

+0

thanks.this现在有道理。我认为我们有动态的类型。但实际上我们不。这就是为什么我不能使用'typeof(动态)'和默认类型是对象。答案。 @AVD –

回答

2

从C#5.0规范,4.7动态类型

类型动态在C#特殊的意义。其目的是允许动态绑定,这在第7.2.2节中有详细描述。 动态被认为与对象相同,除了以下几个方面:
•动态类型表达式的操作可以动态绑定(第7.2.2节)。
•类型推断(第7.5.2节)如果两者都是候选者,则偏好动态优先于对象。
由于此等价的,下式成立:
•有对象和动态之间的隐式标识转换,以及构造类型与对象
替换动态•隐式和显式转换到和从对象也时是相同的间适用于和来自动态。
方法签名更换动态的对象时,被认为是相同的签名

其实是一样的,一旦你的代码被编译,有dynamic为参数的方法是有效地一样的,如果是使用object来声明相同的方法。只是在该方法内部,dynamic参数可以动态使用(即,使用运行时绑定)。

因此,您的第一个示例对方法与您声明两个方法的参数类型为object基本相同。

在你的第二个例子,就像你可以有重载,其中一个有object参数和string其他的参数,所以也可以在配对使用dynamic使用string同名的方法的方法。

根据C#(同样在规范中)的重载解析规则,只要方法参数列表的方式不同,以允许将一个方法重载选择为“最佳”重载,则不会发生编译时错误发生。在您的具体示例中,将除string以外的任何其他项传递给该方法会自动排除string作为参数的方法。在通过string的情况下,重载解析规则选择string重载作为“最佳”重载,所以不会发生编译错误。

+0

感谢您的好解释。特别是重载分辨率选择最佳过载的部分。真的很有帮助。 –