具有派生接口的 C# 接口实现

2024-02-08

在下面的示例中,类“SomeClass”没有实现“ISomeInterface”。为什么我不能通过传递一个更派生的接口来实现这一点,该接口确实实现了基本要求。无论传递什么实例,它仍然会实现基础,我是否遗漏了什么?

namespace Test
{
    public interface IBaseInterface
    {
        void DoBaseStuff();
    }

    public interface IChildInterface : IBaseInterface
    {
        void DoChildStuff();
    }

    public interface ISomeInterface
    {
        void DoSomething(IBaseInterface baseInterface);
    }

    public class SomeClass : ISomeInterface
    {
        public void DoSomething(IChildInterface baseInterface)
        {
        }
    }
}

存在此限制是因为ISomeInterface expects任何IBaseInterface将满足合同。也就是说,如果您有以下情况:

public interface IBase {}
public interface IChildA : IBase {}
public interface IChildB : IBase {}

以及一个期望的界面IBase:

public interface IFoo { void Bar(IBase val); }

然后根据需要在派生类中限制它:

public class Foo : IFoo { public void Bar(IChildA val) {} }

会产生以下问题:

IChildB something = new ChildB();
IFoo something = new Foo();
something.Bar(something); // This is an invalid call

因此,您没有履行您所说的合同。

在这种情况下,你有两个simple选项:

  • Adjust IFoo是通用的,并接受T这是一个推导IBase:

    public interface IFoo<T> where T : IBase { void Bar(T val); }
    public class Foo : IFoo<IChildA> { public void Bar(IChildA val) {} }
    

    当然,这意味着Foo无法再接受any IBase(包括IChildB).

  • Adjust Foo实施IFoo,还有一个额外的实用方法void Bar(IChildA val):

    public class Foo : IFoo
    {
        public void Bar(IBase val) {}
        public void Bar(IChildA val) {}
    }
    

    这有一个有趣的副作用:每当你调用((IFoo)foo).Bar它将期望IBase,当你打电话时foo.Bar它将期望IChildA or IBase。这意味着它满足合同,同时还具有特定于派生接口的方法。如果你想“隐藏”Bar(IBase)方法更多,你可以实现IFoo明确地:

    void IFoo.Bar(IBase val) { }
    

    这创造了代码中的行为不一致,就像现在一样((IFoo)foo).Bar is 完全地不同于foo.Bar,但我把决定权留给你。

    这意味着,在本节的第二个版本中,foo.Bar(new ChildB());现在无效,因为IChildB is not an IChildA.


为什么我不能通过传递一个更派生的接口来实现这一点,该接口确实实现了基本要求。无论传递什么实例,它仍然会实现基础,我是否遗漏了什么?

由于我上面提到的原因,这是不允许的,IFoo.Bar期望any IBase,而你想要further将类型限制为IChildA,即not一个超级接口IBase,即使是,也不会被允许,因为它违反了接口实现,尽管您可以更容易此时定义第二个方法来执行您想要的操作。

请记住,当您实施interface,您订阅了contract,而 C# 将not让你违反那个合同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有派生接口的 C# 接口实现 的相关文章

随机推荐