.NET框架中的错误,使用泛型引用隐藏成员

时间:2018-02-19 12:26:10

标签: c# .net generics frameworks .net-core

我认为.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)。 根据规范,当我们直接引用对象而不是使用父引用时,它应该调用隐藏的成员。 当我们使用泛型时,上述规范不起作用。

1 个答案:

答案 0 :(得分:0)

因为您的show方法位于Handler<TType>中,所以它只能访问Caller类型的方法和属性,因为:Caller constaint。它无法访问NextCaller类型的方法。

如果使用完全相同的方法体为.Show类中的HandlerNext方法创建覆盖,则会因为:NextCaller约束而调用基于NextCaller类型的方法那个班。