C#:传递继承

时间:2011-01-30 23:06:56

标签: c# multiple-inheritance

继承是C#中的传递关系吗?

我在问,因为我无法理解为什么IList<T>实施ICollection<T>IEnumerable<T>,因为ICollection<T>已经实施IEnumerable<T>

感谢您为我澄清这一点。

2 个答案:

答案 0 :(得分:8)

它在所有方面都具有传递性。可能用于查看继承层次结构的工具有一定的显示方式。没有办法实现接口,尽管你可以明确地实现它,从而将它隐藏在intellisense中。

作为IList的作者,您可以自由选择仅从ICollection或ICollection和IEnumerable派生。在这种情况下,IEnumerable将是多余的,并由resharper标记。

答案 1 :(得分:4)

AFAIK,您是否将IList<T>声明为:

并不重要
public interface IList<T> : ICollection<T>, IEnumerable<T> { ... }

或简单地说:

public interface IList<T> : ICollection<T> { ... }

任何想要实现IList<T>的类都必须实现这些接口的所有,即继承的接口。

显然,如果您实现此接口而未实现GetEnumerator / IEnumerable接口的IEnumerable<T>方法,则会出现编译器错误;这个演示的“证据”应该足以告诉你“接口继承”确实是传递性的。


Sidenote 1。在旁注(稍微偏离主题)上,请考虑您还可以执行以下操作:

class Base
{
    public void Foo() { ... }
}

interface IFoo
{
    void Foo();
}

class Derived : Base, IFoo 
{ }

Derived实际上并未实现IFoo;它的基类Base提供了方法Foo,但没有明确地实现IFoo本身。

这很好地编译,似乎因为接口所需的所有方法都存在。 (我会把它留在那里,暂时搁置一下技术性的谈话。)

我之所以提到这个看似无关的现象,是因为我喜欢以这种方式考虑接口继承:你需要实现类声明中指定的接口所需的所有方法。所以,当我看到

interface ICollection<T> : IEnumerable<T> { ... }

而不是说,ICollection<T>继承IEnumerable<T>,我可以对自己说,ICollection<T>要求他们执行所有类同时实施IEnumerable<T>。“


旁注2。以另一个有点相关的轶事(我保证它将是最后一个)结束这个答案:

前段时间我在频道9上观看了视频Inside .NET Rx and IObservable/IObserver in the BCL。正如您现在所知,来自Rx的这两个新界面已经被引入到BCL中。这是一个特殊的事情。当你通过observable.Subscribe(observer)订阅一个观察者观察者时,你得到的只是一些匿名的IDisposable。为什么呢?

正如谈话者在该视频中解释的那样,他们可以通过类型名称“alias”为IDisposable提供更具描述性的名称(例如ISubscription),如下所示:

interface ISubscription : IDisposable {}

然而,他们最终决定反对这一点。他们认为,一旦从ISubscription方法返回Subscribe,返回的值必须为Dipose d就不再明显了。

这是“接口继承”的另一个有问题的方面,应该牢记这一点。