动态类型和其他类型的重载方法 [英] Overloading Method with dynamic and other types

查看:41
本文介绍了动态类型和其他类型的重载方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我不能使用 dynamic object 参数重载方法.

Why I cant overload Method with dynamic and object Parameters.

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 和另一种类型的 except 对象重载Method或自行将其动态重载.

But I can overload Method with dynamic and another type except object or dynamic it self.

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

在第一个示例中可以看到,编译器无法区分两个重载.

As you can see in the first example compiler can't discriminate two overloads.

我认为第二个示例也不应该工作,因为可以将字符串发送到两个重载.但是,编译器更喜欢使用已知类型来调用重载.

I think the second example should not work too because string can be send to both overloads. However Compiler Prefers to call the overload with known type.

我已经进行了一些测试,以了解其实际工作原理.

I've done some test to see how actually it works.

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

考虑第一个示例的工作原理,编译器将做出如下决定:

Consider first example works and compiler would decide like this:

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

那么,编译器的混乱之处在哪里?为什么我不能有这样的超载?

So where is the confusion to the compiler? Why I cant have such overloads?

推荐答案

根据C#5.0规范, 4.7动态类型:

From the C# 5.0 specification, 4.7 The dynamic type:

动态类型在C#中具有特殊含义.其目的是允许动态绑定,这在第7.2.2节中有详细描述.动态被认为与对象相同,但在以下方面除外:
•动态类型的表达式上的操作可以动态绑定(第7.2.2节).
•如果两者都是候选,则类型推断(第7.5.2节)将首选动态而不是对象.
由于这种等效,以下内容成立:
•对象和动态对象之间以及构造的类型之间存在隐式身份转换,当用对象替换动态对象时,它们是相同的
•对对象的隐式和显式转换也适用于动态.
用对象替换动态对象时相同的方法签名被视为相同的签名

The type dynamic has special meaning in C#. Its purpose is to allow dynamic binding, which is described in detail in §7.2.2. dynamic is considered identical to object except in the following respects:
• Operations on expressions of type dynamic can be dynamically bound (§7.2.2).
• Type inference (§7.5.2) will prefer dynamic over object if both are candidates.
Because of this equivalence, the following holds:
• There is an implicit identity conversion between object and dynamic, and between constructed types that are the same when replacing dynamic with object
• Implicit and explicit conversions to and from object also apply to and from dynamic.
Method signatures that are the same when replacing dynamic with object are considered the same signature

实际上,一旦编译了代码,以 dynamic 作为参数的方法实际上与使用 object 声明相同方法的方法相同.只是在方法内部,可以动态地使用 dynamic 参数(即与运行时绑定一起使用).

In fact, once your code is compiled, a method having dynamic as a parameter is effectively the same as if that same method were declared using object. It's simply that inside the method, the dynamic parameter can be used dynamically (i.e. with run-time binding).

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

Because of this, your first example pair of methods is essentially the same as if you'd declared both methods with the parameter type of object.

在第二个示例中,就像您可以重载一样,其中一个重载的参数为 object ,而另一个重载的参数为 string ,因此您也可以将一个方法配对使用 dynamic 和使用 string 的同名方法.

In your second example, just as you can have overloads where one has a parameter of object and the other a parameter of string, so too can you pair a method using dynamic with a method of the same name using string.

根据C#的重载解析规则(也在规范中),只要方法参数列表的不同方式允许将一种方法重载选择为最佳"重载,则不会发生编译时错误.在您的特定示例中,将 string 以外的任何其他内容传递给该方法会自动排除以 string 作为参数的方法.如果您确实传递了 string ,则重载解析规则将 string 重载选择为最佳"重载,因此不会发生编译错误.

Per the overload resolution rules for C# (also in the specification), as long as the method parameter lists are different in ways that allow one method overload to be chosen as the "best" overload, no compile-time error will occur. In your specific example, passing anything other than a string to the method automatically excludes the method with string as a parameter. In the case where you do pass string, the overload resolution rules select the string overload as the "best" overload, so no compile error occurs.

这篇关于动态类型和其他类型的重载方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆