【问题标题】:Overloading Method with dynamic and other types动态和其他类型的重载方法
【发布时间】:2015-07-13 02:26:54
【问题描述】:

为什么我不能用dynamic 和object 参数重载方法。

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");
}

但我可以重载 Method 与 dynamic 和另一种类型 except 对象或动态它自己。

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.

那么编译器的困惑在哪里?为什么我不能有这样的重载?

【问题讨论】:

  • 动态的默认类型是object。 (MSDN)
  • 谢谢。现在说得通了。我以为我们有动态类型。但实际上我们没有。这就是为什么我不能使用typeof(dynamic) 并且默认类型是对象。答案。 @AVD

标签: c# object dynamic overloading


【解决方案1】:

来自 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 重载作为“最佳”重载,因此不会发生编译错误。

【讨论】:

  • 感谢您的精彩解释。特别是重载决议选择最佳重载的部分。真的很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
  • 1970-01-01
  • 2011-12-30
  • 1970-01-01
  • 1970-01-01
  • 2011-08-23
相关资源
最近更新 更多