我认为.NET框架中应该存在一个错误,根据规范"当我们直接引用对象而不是使用父引用时,它应该调用隐藏成员"。
对于相同的情况,我使用了泛型,但不支持更多理解,请仔细阅读代码和输出以供参考。
示例代码可以在这里找到。
public class A
{
public A()
{
Console.WriteLine("A ctor called");
Property=111;
}
public int Property { get; set; }
}
public class B
{
public B()
{
Console.WriteLine("B ctor called");
Property=222;
}
public int Property { get; set; }
}
-----没有泛型-----------
public class Caller
{
public virtual int Property { get; set; }
public Caller()
{
Property=4444;
}
public A GetDevice()
{
return new A();
}
}
public class NextCaller:Caller
{
public NextCaller()
{
Property=5464654;
}
public new B GetDevice()
{
return new B();
}
}
-----With Generics-----------
public interface ReferenceType<TType> where TType:Caller
{
TType GetCurrentType();
}
public class Handler<TType>:ReferenceType<TType> where TType:Caller
{
public virtual TType CurrentObj {get;set;}
public virtual TType GetCurrentType()
{
return CurrentObj as TType;
}
public virtual void Show()
{
var type=GetCurrentType();
Console.WriteLine(CurrentObj.Property);
Console.WriteLine(GetCurrentType().GetDevice().Property);
}
}
public class HandlerNext<TType> : Handler<TType> where TType:NextCaller
{
public override TType CurrentObj {get;set;}
public override TType GetCurrentType()
{
return CurrentObj;
}
}
-------用法演示-------------------
public class UsageDemo
{
public void Main()
{
//using generics
var handler=new Handler<Caller>();
handler.CurrentObj=new NextCaller();
handler.Show();
var handler1=new HandlerNext<NextCaller>();
handler1.CurrentObj=new NextCaller();
handler1.Show();
//with out using generics
Caller handle=new NextCaller();
Console.WriteLine(handle.GetDevice().Property);
NextCaller handle1=new NextCaller();
Console.WriteLine(handle1.GetDevice().Property);
}
}
//使用泛型
这里是一个ctor calledenter代码
111个
一个叫做的人
111个
//没有使用泛型
一个叫做的人
111个
B ctor叫
222个
这里的问题是,
在这四个输出中,第二个输出显示错误的结果,因为我使用泛型推断结果。如果我们在不使用泛型的情况下在输出中看到结果它正常工作(参见输出4)。
根据规范,当我们直接引用对象而不是使用父引用时,它应该调用隐藏的成员。
当我们使用泛型时,上述规范不起作用。
答案 0 :(得分:0)
因为您的show方法位于Handler<TType>
中,所以它只能访问Caller类型的方法和属性,因为:Caller
constaint。它无法访问NextCaller类型的方法。
如果使用完全相同的方法体为.Show
类中的HandlerNext
方法创建覆盖,则会因为:NextCaller
约束而调用基于NextCaller类型的方法那个班。