代码之家  ›  专栏  ›  技术社区  ›  Piotr Czapla

为什么C在实现接口时不允许继承返回类型

  •  21
  • Piotr Czapla  · 技术社区  · 15 年前

    下面的代码在C中不合法有什么合理的原因吗?

    class X: IA, IB
    {
        public X test() // Compliation Error, saying that X is not IB
        {
            return this;
        }
    }
    
    interface IA 
    {
        IB test();
    }
    interface IB { };
    
    6 回复  |  直到 13 年前
        1
  •  30
  •   Eric Lippert    15 年前

    这个特性称为“返回类型协方差”。C不支持它,原因如下:

    1)clr不支持。为了使它在C中工作,我们只需要吐出一堆小助手方法,这些方法对返回类型进行强制转换,以得到正确的结果。没有什么能阻止你自己去做。

    2)Anders认为返回类型协方差不是一个好的语言特性。

    3)我们对语言有很多更高的优先级。我们只有有限的预算,所以我们尽量在任何给定的版本中尽可能做到最好的功能。当然,这很好,但如果你愿意的话,你自己做就足够容易了。更好的方法是我们花时间添加一些功能来改善开发人员的体验,或者为语言添加更多的代表性功能。

        2
  •  16
  •   Brian Gideon    15 年前

    您可以使用显式接口实现来避免这个问题。

    class  X : IA, IB
    {
      public X test()
      {
        return this;
      }
    
      IB IA.test()
      {
        return this;
      }
    }
    
    interface IA
    {
      IB test();
    }
    
    interface IB
    {
    }
    
        3
  •  5
  •   Thorarin    15 年前

    签名必须与接口指定的完全匹配。您没有理由不能返回的实例 X 但方法签名必须使用 IB .

    因为合理的原因……从代码可读性的角度来看,这可能更可取。

    可以显式实现接口,并提供返回 X 接口没有定义。如果你知道你的 IA 实际上是一个 X 你可以用它来代替。

        4
  •  3
  •   Przemaas    15 年前

    因为C在编译时不支持接口的co和contravriance。这样,ia.test()方法的实现必须与其声明完全匹配。但是,您可以在运行时返回x的实例

        5
  •  1
  •   skalb    15 年前
    public X test();
    

    必须为任何非抽象类中的所有方法声明主体。

    试试这个:

    class X : IA, IB
    {
        public IB test()
        {
            return new X();
        }
    }
    
    interface IA
    {
        IB test();
    }
    interface IB { };
    
        6
  •  1
  •   user958933    13 年前