¿Por qué las clases de colecciones en C # (como ArrayList) heredan de varias interfaces si una de estas interfaces hereda de las restantes?

StackOverflow https://stackoverflow.com/questions/1023375

Pregunta

Cuando presiono f12 en la palabra clave ArrayList para ir a los metadatos generados a partir de vs2008, descubrí que la declaración de clase generada es la siguiente

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

Sé que IList ya hereda de ICollection e IEnumerable, entonces, ¿por qué ArrayList hereda de forma redundante de estas interfaces?

¿Fue útil?

Solución

Bien, he investigado un poco. Si crea la siguiente jerarquía:

  public interface One
    {
        void DoIt();
    }

    public interface Two : One
    {
        void DoItMore();
    }

    public class Magic : Two
    { 
        public void DoItMore()
        {
            throw new NotImplementedException();
        }

        public void DoIt()
        {
            throw new NotImplementedException();
        }
    }

Y compílelo, luego haga referencia a la DLL en una solución diferente, escriba Magic y presione F12, obtendrá lo siguiente:

 public class Magic : Two, One
    {
        public Magic();

        public void DoIt();
        public void DoItMore();
    }

¿Verá que la jerarquía de la interfaz está aplanada o que el compilador agrega las interfaces? Si usa el reflector, obtendrá los mismos resultados también.

Actualización: si abre la DLL en ILDASM, verá que dice:

implementa ... Dos

implementa ... Uno.

Otros consejos

Las interfaces adicionales se muestran porque están implicadas por IList. Si implementa IList, también debe implementar ICollection e IEnumerable.

Solo estoy adivinando, pero creo que en realidad solo implementa IList en el código, pero la documentación también muestra el resto de las interfaces para hacerlo explícito al programador que usa la clase.

De MSDN ....

  

Si una clase implementa dos interfaces   que contienen un miembro con el mismo   firma, luego implementando eso   miembro de la clase causará tanto   interfaces para usar ese miembro como su   implementación.

     

La implementación explícita también se usa   para resolver casos donde dos interfaces   cada uno declara diferentes miembros de la   mismo nombre como una propiedad y un   método:

No acepte esto como respuesta.

Estoy repitiendo lo que workmad3 dijo anteriormente.

Al implementarlo en ArrayList, resulta fácil para uno saber qué interfaces implementa ArrayList en lugar de ir a IList para encontrar que implementa ICollection & amp; IEnumerable.

Eso evita la necesidad de retroceder & amp; adelante la cadena de herencia.

EDITAR: en el nivel básico, una interfaz que implementa otra interfaz no puede proporcionar la implementación. La clase derivada (de IList) implementa indirectamente ICollection & amp; IEnumerable también. Entonces, incluso si escribe su propia clase implementando IList (y no agrega ICollection, IEnumerable en la declaración), verá que tendrá que proporcionar la implementación para ICollection & amp; IEnumerable.

Y el razonamiento de workmad3 tiene sentido.

Supongo que CLR no admite una interfaz que herede de otra interfaz.

C #, sin embargo, admite esta construcción, pero tiene que 'aplanar' el árbol de herencia para que sea compatible con CLR.

[Editar]

Después de seguir los consejos de abajo, configure rápidamente un proyecto VB.Net:

Public Interface IOne
    Sub DoIt()
End Interface

Public Interface ITwo
    Inherits IOne
    Sub DoIt2()
End Interface

Public Class Class1
    Implements ITwo

    Public Sub DoIt() Implements IOne.DoIt
        Throw New NotImplementedException()
    End Sub

    Public Sub DoIt2() Implements ITwo.DoIt2
        Throw New NotImplementedException()
    End Sub
End Class

Compilación de resultados en el siguiente (C #):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

Esto muestra que VB.Net NO aplana la jerarquía de la interfaz en lugar de C #. No tengo idea de por qué esto sería.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top