问题 C#:传递继承


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

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

谢谢你为我澄清这一点。


1615
2018-01-30 23:06


起源

你可以在这个类似的[问题] [1] [1]中找到一些答案: stackoverflow.com/questions/1164757/... - DesignFirst
stackoverflow.com/questions/4754923/... - explorer
这也是重复的 stackoverflow.com/questions/4817369/... - Eric Lippert


答案:


AFAIK,你是否申报并不重要 IList<T> 如:

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

或简单地说:

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

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

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


旁注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。 用另一个有点相关的轶事来结束这个答案(我保证它将是最后一个):

前段时间我看了视频 在.NET Rx和 IObservable/IObserver 在BCL 在Channel 9上。正如你现在所知,这两个新接口来自 RX,用.NET 4引入BCL。一个特殊的事情就是当你订阅一个观察者来观察一个观察者 observable.Subscribe(observer)你得到的一切都是匿名的 IDisposable。为什么?

正如谈话者在那段视频中解释的那样,他们本可以给出 IDisposable 更具描述性的名称(例如 ISubscription),通过类型名称“别名”定义如下:

interface ISubscription : IDisposable {}

然而,他们最终决定反对这一点。他们认为曾经一度 ISubscription 从...返回 Subscribe 方法,返回的值不再是显而易见的 Diposed。

所以这是“界面继承”的另一个有问题的方面,应该记住。


4
2018-01-30 23:21





它在所有方面都具有传递性。可能用于查看继承层次结构的工具有一定的显示方式。虽然您可以明确地实现它并从而将其隐藏在智能感知中,但是无法实现接口的实现。

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


8
2018-01-30 23:14



对不起打扰,但“和resharper标记”引起了我的注意。 Resharper只是一个工具,而不是编程大师。它还标记了许多其他事情,如果改变后来会引起麻烦。 (例如,将显式声明标记为隐式(var)) - kubal5003
是。我只是意味着这句话给出了社会证明,那就是编程重塑者和我一致。 - usr