为什么我不能在用具体类型代替接口的类上实现接口

本文关键字:接口 实现 类型 不能 为什么 | 更新日期: 2023-09-27 17:50:06

为什么不能做以下操作?

public class TestClass : TestInterface
{
    public ClassX Property { get; private set; }
}
public interface TestInterface
{
    InterfaceX Property { get; }
}
public interface InterfaceX
{
}
public class ClassX : InterfaceX
{
}

TestInterface属性是只读的,因此根据合约只能返回InterfaceX。

然而,我得到这个编译错误:

'TestClass'没有实现接口成员"TestInterface.InterfaceX"。"TestClass。InterfaceX'无法实现"TestInterface。因为它没有匹配返回'InterfaceX'的类型。

它没有匹配的类型,但它有该类型的子类

为什么我不能在用具体类型代替接口的类上实现接口

我不知道规范,但我肯定有一个明确地声明返回类型必须完全匹配接口实现。我能找到的最近的是13.4.4:

对于接口映射,类成员a在下列情况下匹配接口成员B:

  • A和B为方法,A和B的名称、类型和形式参数表相同。
  • A和B是属性,A和B的名称和类型相同,并且A具有与B相同的访问器(如果A不是显式接口成员实现,则允许有额外的访问器)。

如果上面的"type"表示"返回类型",则表示返回类型不能更改。

但是,您可以更改返回类型并显式地使用正确的返回类型实现接口:
public class TestClass : TestInterface
{
    public ClassX InterfaceX { get; private set; }
    InterfaceX TestInterface.InterfaceX { get { return InterfaceX; } }
}

更新

根据Eric Lippert的说法,这似乎是CLR的限制,而不仅仅是c#的限制

您提到您想要公开一个约简集,但是您想要类内部的所有功能—这不是您想使用接口的目的。接口应该只是关于你的简化集契约,而不是在内部神奇地作为一个完整的集合,不能没有另一个辅助属性。

但是,有一种方法可以绕过这个限制,同时仍然可以稍微交流合约。

interface IExpose<IToolType> where IToolType : ITool
{
  IToolType Handler { get; set; }
}
class Expose : IExpose<Tool>
{
  public Tool Handler { get; set; }
}
interface ITool
{
}
class Tool : ITool
{
}