是C#中的方法重载多态性Early Bound

本文关键字:多态性 Early Bound 重载 方法 | 更新日期: 2023-09-27 18:26:47

在C#中,如果我有

public class BaseClass
{
    //BaseClass implementation
}
public class Derived : BaseClass
{
    //Derived implementation
}
public class AnotherClass
{
    AnotherClass(BaseClass baseClass)
    {
        //Some code
    }
    AnotherClass(Derived derived) : this(derived as BaseClass)
    {
        //Some more code
    }
}

然后做:

BaseClass    baseVariable    = new Derived();
AnotherClass anotherVariable = new AnotherClass(baseVariable);

这将导致早期绑定,调用AnotherClass(BaseClass)方法。

相反,如果我使用dynamic关键字强制转换它,或者用dynamic实例化一个变量,然后将其作为构造函数参数传递,则会调用AnotherClass(Derived)

BaseClass    baseVariable    = new Derived();
//This will instantiate it using the AnotherClass(Derived)
AnotherClass anotherVariable = new AnotherClass(baseVariable as dynamic);

方法是否重载了C#中的早期绑定(在编译时求值)?也就是说,在不使用dynamic或反射的情况下,是否有其他方法或技巧来确定对其他类构造函数的主要派生调用,以应用对以主要派生类类型为参数的构造函数的调用?

是C#中的方法重载多态性Early Bound

C#中的绑定时间取决于绑定是否涉及dynamic。正如您所看到的,如果您使用dynamic,您将获得执行时间过载解决方案;如果不这样做,您将获得编译时过载解决方案。

请注意,即使重载解析涉及动态类型,它仍然会使用编译时已知的信息——只有dynamic类型的表达式使用执行时类型。示例:

using System;
class Test
{
    static void Main()
    {
        object x = "abc";
        dynamic y = 10;
        Foo(x, y); // Prints Foo(object,int)
    }
    static void Foo(object x, int y)
    {
        Console.WriteLine("Foo(object,int)");
    }
    static void Foo(string x, int y)
    {
        Console.WriteLine("Foo(string,int)");
    }
}

如果您将声明的x类型更改为dynamic执行时间类型将是相关的(它将打印Foo(string,int))。

当然,这只是过载解决方案-重写总是在执行时确定的,除非您使用非虚拟调用(调用非虚拟方法或使用base.Foo(...)

关于此位:

是否有其他方法或技巧来确定对其他类构造函数分离反射的主要派生调用?

找出存储在引用中的对象的最派生类型的唯一方法是询问它(使用GetType或其他方法)。所以不,反思在这里是不可避免的。

如果您已经知道最派生的类型是什么,那么当然可以在传入之前转换为它,以便在编译时选择适当的重载。您也可以在第一个代码段中使用var来自动使用引用的派生类型最多的类型。