代码之家  ›  专栏  ›  技术社区  ›  tobiak777

无法隐藏继承的成员编译器错误

  •  2
  • tobiak777  · 技术社区  · 8 年前

    我正在努力:

    public abstract class Base
    {
        public abstract Task Execute(); 
    }
    
    public abstract class Concrete<T> : Base where T : class
    {
        new public abstract Task<T> Execute();
    }
    

    但由于某些原因,我得到了编译器错误:

    CS0533混凝土。Execute()'隐藏继承的抽象成员'Program.Base.Execute'()

    我过去隐藏了很多成员,但从未遇到过这个附带案例,我对此感到很困惑。在MSDN和网络上花了很长时间,但找不到任何关于这种行为的信息。

    我非常感谢对这个问题的任何见解。

    这里是 the fiddle .

    2 回复  |  直到 8 年前
        1
  •  4
  •   svick bala    8 年前

    问题是基本方法是 abstract 。继承自的类 Concrete<T> 不得不 推翻 Base.Execute() ,但它 不能够 Derived<T>.Execute() 所以 混凝土<T> 将是一个 摘要 类不可能有任何实现(至少在C#中没有),因此它将是无用的。因此,C#编译器不允许您编写它。

    如果 Base 是一个接口,您可以通过使用显式接口实现来解决这个问题。但是没有什么比显式基类实现更好的了,所以我认为没有任何方法可以拥有这种代码,至少在重命名这两个方法中的一个之前是这样的。

        2
  •  1
  •   Fabjan    8 年前

    来自MSDN:

    抽象方法声明引入了一个新的虚拟方法,但是 不提供该方法的实现。相反 非抽象派生类需要提供它们自己的 通过重写该方法实现

    嗯,这个错误的原因是抽象在C#中是如何工作的,抽象可以被继承,可以实现,但不能被另一个抽象隐藏或替换。

    此外,考虑代码:

    public abstract class Base
    {
        public abstract Task Execute();
        public abstract Task<int> Execute();
    }
    

    这不会编译,因为:

    类型“Base”已定义名为“Execute”的成员 参数类型

    那么,当我们将第二个方法移动到派生抽象类时,为什么它应该工作呢?