多态方法不能在c# 4中工作

本文关键字:工作 方法 不能 多态 | 更新日期: 2023-09-27 18:14:48

我偶然发现了一个非常有趣的问题。给出如下代码:

using System;
class Program
{
    class A { }
    class B : A { }
    private static void MyMethod(A a) /* first method */
    {
        Console.WriteLine("A"); ;
    }
    private static void MyMethod(B b) /* second method */
    {
        Console.WriteLine("B");
    }
    static void Main(string[] args)
    {
        var a = new A();
        // Call first method
        MyMethod(a);
        A b = new B();
        // Should call the second method
        MyMethod(b);
        Console.ReadLine();
    }
}

我希望第二个方法将被调用,因为变量的运行时类型是b。任何想法为什么代码调用第一个方法代替?

谢谢,Tibi

少数

澄清一下:多态性意味着几种形式,与你声明方法的位置无关。

方法重载是多态性的一种形式,ad-hoc多态性。

多态性通常是通过使用后期绑定实现的。

dynamic是解决这个问题的方法。

事实是,这在c#(或Java)中不起作用,这是一个设计决策,我想了解为什么要这样做,没有一个答案可以回答这个问题。

/Tibi

少数

多态方法不能在c# 4中工作

这根本不是多态性的例子。当您在对象上调用方法时,而不是将对象用作参数时,多态就会发挥作用。这只是一个方法重载的简单例子。

你将b声明为A类型,因此编译器将链接到使用A类型的重载。链接器并不关心b是否是A的子类,它只选择与传入参数的声明类型(而不是实际类型)签名最接近的重载。

如果你想强迫它使用第二个方法,在方法调用中将b in强制转换为类型b。

MyMethod((B)b);

c#中的方法重载,默认情况下是在编译时静态确定的。由于您传递的是a类型的静态类型变量,因此它将静态绑定到具有a重载的方法。使用dynamic关键字来获得你想要的行为。

static void Main(string[] args)
{
    dynamic d = new A();
    // Call first method
    MyMethod(d);
    d = new B();
    // Call the second method
    MyMethod(d);
    Console.ReadLine();
}

没有调用第二个方法,因为对b的引用本身是A类型的。虽然b包含对B实例的引用,但这不是B的实际类型,因此选择使用A引用的重载。