【问题标题】:Bug in .NET framework, reference hidden member using generics [duplicate].NET 框架中的错误,使用泛型引用隐藏成员 [重复]
【发布时间】:2018-07-29 16:34:08
【问题描述】:

我认为 .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);
    }
}

输出:-

//使用泛型
一个调用者在这里输入代码
111
一个演员叫
111
//不使用泛型
一个演员叫
111
被称为 B ctor 222

问题来了,
在这四个输出中,第二个输出显示了错误的结果,因为我使用泛型推断了结果。如果我们在不使用泛型的情况下看到输出结果,则它可以正常工作(请参阅输出 4)。 根据规范,当我们直接引用对象而不是使用父引用时,它应该调用隐藏成员。 当我们使用泛型时,上述规范不起作用。

【问题讨论】:

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


    【解决方案1】:

    由于您的 show 方法在 Handler&lt;TType&gt; 中,因此由于 :Caller 约束,它只能访问 Caller 类型的方法和属性。它不能访问 NextCaller 类型的方法。

    如果您使用完全相同的方法主体在 HandlerNext 类中创建 .Show 方法的覆盖,由于该类的 :NextCaller 约束,它将调用基于 NextCaller 类型的方法。

    【讨论】:

    • 是的。这是正确的,但是当我们调试它时,它在 CurrentObj 属性中显示 Handler 类中的 NextCaller 对象。基本上我的概念是使用相同的引用来调用隐藏的成员。
    • CurrentObj 属性中的对象是 NextCaller 对象,但是您的 .Show 方法是在 Handler 基类中实现的,它将其视为 Caller 对象。由于它将其视为 Caller 对象,因此它从 Caller 对象调用隐藏的 GetDevice 方法,而不是从 NextCaller 对象调用 GetDevice 方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多