db4*_*b42 3 c# generics overriding interface
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在此Client.Init()返回"Add with parameter - TimedDoor"
但是如果Client没有覆盖Init(),
public class Client : BaseClient<TimedDoor>
{
public Client()
{
TimedDoor = new TimedDoor();
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,Client.Init()返回"Add with parameter - ITimeable"
这是怎么回事?TimedDoorObject两种情况下在运行时都是相同的.
如果我们添加一些显式的强制转换来表示T在该点Timer.Add(TimedDoorObject)被调用的内容,那么它会更明显地发生什么.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当它被编译时,BaseClient它知道是T某种ITimeable对象,因此它能够链接到的最佳超载是void Add(ITimeable obj)版本.相比之下,在编译时Client知道T代表一个TimedDoor所以它使用void Add(TimedDoor obj)函数,因为它是一个更好的匹配void Add(ITimeable obj).