2011-01-30 15 views
11

¿Es la herencia una relación transitiva en C#?C#: Herencia transitiva

Estoy pidiendo porque no puedo entender por qué IList<T> implementa ICollection<T> y IEnumerable<T> como ICollection<T> ya implementa IEnumerable<T>

Gracias por aclarar esto para mí.

+0

se pueden encontrar algunas respuestas en esta similares [pregunta] [1] [1]: http://stackoverflow.com/questions/1164757/why-arraylist-implement-ilist-icollection-ienumerable – DesignFirst

+0

http://stackoverflow.com/questions/4754923/a-question-about-interface-inheritance-in-net/4755044#4755044 – explorer

+0

Este también es un duplicado de http://stackoverflow.com/questions/4817369/why -does-does-realy-list-implements-all-of-that-interfaces-not-just-ilistt/4818566 # 4818566 –

Respuesta

4

yo sepa, no tiene realmente importa si usted declaró IList<T> como:

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

o simplemente como:

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

Cualquier clase que quiere implementar IList<T> tendrá que poner en práctica todos los de estas interfaces, es decir, también las heredadas.

Obviamente, si implementó esta interfaz sin implementar los métodos GetEnumerator de las interfaces IEnumerable/IEnumerable<T>, obtendría un error de compilación; esta "demostración" por demostración debería ser suficiente para decirte que la "herencia de la interfaz" es transitiva, de hecho.


Nota al margen 1. En una nota lateral (y un poco fuera de tema), tenga en cuenta que también se puede hacer lo siguiente:

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

interface IFoo 
{ 
    void Foo(); 
} 

class Derived : Base, IFoo 
{ } 

Derived en realidad no implemento IFoo; su clase base Base proporciona el método Foo, pero no implementa explícitamente IFoo.

Esto compila bien, aparentemente porque todos los métodos requeridos por las interfaces están ahí. (Lo dejaré así y dejo la charla técnica exacta a un lado por el momento).

La razón por la que menciono este fenómeno aparentemente no relacionado es que me gusta pensar en la herencia de interfaz de esta manera: necesita implementar todos los métodos requeridos por las interfaces especificadas en la declaración de clase. Así que cuando veo

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

en lugar de decir, "ICollection<T> hereda IEnumerable<T>", podría decir a mí mismo, "ICollection<T> requiere de todas las clases de aplicación que implementan IEnumerable<T>, también."


Nota al margen 2. Para concluir esta respuesta con otra anécdota más o menos relacionada (prometo que será la última):

Hace un tiempo vi el video Inside .NET Rx and IObservable/IObserver in the BCL en el canal 9. Como puedes ver ahora, esas dos nuevas interfaces, que vienen desde Rx, se introdujeron en el BCL con .NET 4. Una cosa peculiar es que cuando se suscribe un observador a un observable a través de observable.Subscribe(observer), todo lo que recibe es algo anónimo IDisposable. ¿Por qué?

Como los habladores explican en ese video, que podrían haber dado el nombre más descriptivo IDisposable (como ISubscription), a través de un nombre de tipo "alias" definido de la siguiente manera:

interface ISubscription : IDisposable {} 

Sin embargo, finalmente decidido contra esto. Supusieron que una vez que se devuelve ISubscription del método Subscribe, ya no sería obvio que el valor devuelto debe ser Dipose d.

Así que ese es otro lado ligeramente problemático de la "herencia de interfaz" que uno debe tener en cuenta.

8

Es transitivo en todos los aspectos. Probablemente la herramienta que utiliza para observar la jerarquía de herencia tiene una cierta forma de mostrarla. No hay forma de implementar una interfaz aunque puedes implementarla de manera explícita y así ocultarla de intellisense.

Como autor de IList, puede elegir libremente derivar solo de ICollection o de ICollection e IEnumerable. IEnumerable sería redundante en este caso y marcado por reafilado.

+0

Perdón por interrumpir, pero "y marcado por resharper" me llamó la atención. Resharper es solo una herramienta, no un gurú de la programación. También marca muchas otras cosas que si cambian causan problemas más adelante. (por ejemplo, banderas de declaraciones explícitas que se cambiarán a implícitas (var)) – kubal5003

+0

Sí. Solo quise decir esa frase para dar una prueba social de que la gente que programa la reactivación está de acuerdo conmigo. – usr