代码如下:
public class Person { public void Say() { Console.WriteLine("Person.Say"); } } public class Chinese:Person { public new void Say() { Console.WriteLine("Chinese.Say"); } } public class SayHello<T> where T:Person,new(){ public void Say() { T t = new T(); t.Say(); } } public class Company : SayHello<Chinese> { public void SayC() { Chinese c = new Chinese(); c.Say(); } }
调用代码:
static void Main(string[] args) { Company c = new Company(); c.Say();//Person.Say c.SayC();//Chinese.Say
Console.ReadKey(); }
问题是:为什么 c.Say() 这里不是调用被new覆盖的方法显示 Chinese.Say ,而是调用了父类方法显示的:Person.Say
调试断点在 T t = new T();这里,显示t被实例化为Chinese,但是为什么还是调用的父类的方法?
如果我一定要访问子类自己用new覆盖父类的方法怎么办?
T t = new T();这时T是父类
因为你的约束用的是父类约束,所以得到的引用是父类引用.所以调用的成员是父类成员,而且你用的是new关键字.不是继承,如果用继承重写的话,
但是我调试断点在 T t = new T();这里,显示t被实例化为Chinese,但是为什么还是调用的父类的方法?
@我是流氓: 你在t.Say()这里的Say上面右键,转到定义
会发现这个方法本来就是Person的
@ChuckLu:
public class SayHello<T> where T : Person, new()
{
public void Say()
{
T t = new T();
if (t is Chinese)
{
Chinese c = t as Chinese;
t.Say();
c.Say();
}
}
}
改成这个样子,你试试
new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏。 override 修饰符会扩展继承成员的实现。
https://msdn.microsoft.com/zh-cn/library/435f1dw2.aspx
https://msdn.microsoft.com/zh-cn/library/ms173153.aspx
Chinese被隐式转换为Person了,因为你泛型的约束是Person类型