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

当我实现一个基类也实现的接口时,为什么不得到编译器警告?

  •  4
  • scobi  · 技术社区  · 14 年前

    在下面的代码中,我将实现一个接口,然后从该类派生并实现相同的接口。当我释放派生类的实例时,它只调用派生实现。

    为什么C编译器不对此发出警告?这看起来很危险,有几个原因。我可以实现一个基已经实现的接口,这将提供我不期望的行为(例如,基不再处理)。或者,如果我稍后决定让一个基实现一个新的接口,我必须扫描所有代码以找到任何可能已经实现它的派生。

    对于派生类中的重复成员,编译器要求我们使用“override”或“new”。

    为什么界面不同?

    class CA : IDisposable
    {
        void IDisposable.Dispose() { Debug.WriteLine("CA.Dispose"); }
    }
    
    class CB : CA, IDisposable
    {
        void IDisposable.Dispose() { Debug.WriteLine("CB.Dispose"); }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            using (new CB()) { }
        }
    }
    
    // output: CB.Dispose
    
    1 回复  |  直到 14 年前
        1
  •  6
  •   Jon Skeet    14 年前

    这只是因为您使用的是显式接口实现。例如,这不会编译:

    using System;
    using System.Diagnostics;
    
    class CA : IDisposable
    {
        public void Dispose()
        {
            Debug.WriteLine("CA.Dispose");
        }
    }
    
    class CB : CA, IDisposable
    {
        public void Dispose()
        {
            Debug.WriteLine("CB.Dispose");
        }
    }
    

    所以是的,您需要小心显式接口实现。总是这样,因为不管怎样,在类型系统方面有点奇怪。

    这并不理想,但是显式接口实现在一定程度上是为了避开尴尬的情况 希望 能够重新实现一个接口。

    老实说,如果您在后期决定基类应该开始实现 IDisposable 不管怎样,你处在一个受伤的世界中-因为你必须检查你正在使用该类的每个地方,以判断你是否需要一个 using 语句。