编程语言
首页 > 编程语言> > c# – 为什么调用这个重写方法?

c# – 为什么调用这个重写方法?

作者:互联网

public interface ITimeable     {}
public class TimedDoor : ITimeable  {}

public static class Timer
{
    public static void Add(ITimeable obj)
    {
       Console.Write("Add with parameter - ITimeable"); 
    }

    public static void Add(TimedDoor obj)
    {
       Console.Write("Add with parameter - TimedDoor"); 
    }
}

public class BaseClient<T> where T : ITimeable
{
    public T TimedDoorObject;
    public virtual void Init()
    {
        Timer.Add(TimedDoorObject);
    }
}

public class Client : BaseClient<TimedDoor>
{
    public Client()
    {
        TimedDoorObject = new TimedDoor();
    }

    public override void Init()
    {
        Timer.Add(TimedDoorObject);
    }
}

在此Client.Init()返回“添加参数 – TimedDoor”

但是如果Client没有覆盖Init(),

public class Client : BaseClient<TimedDoor>
{
    public Client()
    {
        TimedDoor = new TimedDoor();
    }
}

这里,Client.Init()返回“Add with parameter – ITimeable”

这是怎么回事?在运行时两种情况下,TimedDoorObject都是相同的.

解决方法:

如果我们添加一些显式的强制转换,表示在调用Timer.Add(TimedDoorObject)时T代表什么,它会使发生的事情变得更加明显.

public class BaseClient<T> where T : ITimeable
{
    public T TimedDoorObject;
    public virtual void Init()
    {
        Timer.Add((ITimeable)TimedDoorObject);
    }
}

public class Client : BaseClient<TimedDoor>
{
    public Client()
    {
        TimedDoorObject = new TimedDoor();
    }

    public override void Init()
    {
        Timer.Add((TimedDoor)TimedDoorObject);
    }
}

因此,当BaseClient被编译时,它知道T是某种ITimeable对象,因此它能够链接到的最佳重载是void Add(ITimeable obj)版本.相比之下,在编译时客户端知道T表示TimedDoor,因此它使用void Add(TimedDoor obj)函数,因为它比void Add(ITimeable obj)更好地匹配.

标签:c,interface,generics,method-overriding
来源: https://codeday.me/bug/20190715/1467875.html