继承是C#中的传递关系吗?
我在问,因为我无法理解为什么IList<T>
实施ICollection<T>
和IEnumerable<T>
,因为ICollection<T>
已经实施IEnumerable<T>
感谢您为我澄清这一点。
答案 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就不再明显了。
这是“接口继承”的另一个有问题的方面,应该牢记这一点。