listas - ¿Por qué las clases de colecciones en C#(como ArrayList) heredan de múltiples interfaces si una de estas interfaces hereda del resto?
colecciones genericas c# (6)
Creo que CLR no admite una interfaz que herede de otra interfaz.
Sin embargo, C # admite este constructo, pero tiene que "aplanar" el árbol de herencia para que cumpla con CLR.
[Editar]
Después de tomar consejo desde abajo, configure rápidamente un proyecto de 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 lo siguiente (C #):
public class Class1 : ITwo
{
public Class1();
public void DoIt();
public void DoIt2();
}
Este programa muestra que VB.Net NO aplana la jerarquía de la interfaz en lugar de C #. No tengo idea de por qué sería esto.
Cuando presiono f12 en la palabra clave ArrayList para ir a los metadatos generados desde vs2008, encontré que la declaración de clase generada es la siguiente
public class ArrayList : IList, ICollection, IEnumerable, ICloneable
Sé que el IList ya hereda de ICollection e IEnumerable, entonces ¿por qué ArrayList hereda de forma redundante estas interfaces?
De acuerdo, hice una investigación. 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 compilarlo, luego hacer 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 el compilador está agregando las interfaces en? Si usas un reflector obtienes los mismos resultados también.
Actualización: si abre el archivo DLL en ILDASM, lo verá diciendo:
implementa ... Dos
implementa ... Uno.
Desde MSDN ...
Si una clase implementa dos interfaces que contienen un miembro con la misma firma, implementar ese miembro en la clase hará que ambas interfaces usen ese miembro como su implementación.
La implementación explícita también se usa para resolver casos en los que dos interfaces declaran diferentes miembros del mismo nombre, como una propiedad y un método:
Las interfaces adicionales se muestran porque están implícitas en IList. Si implementa IList, también debe implementar ICollection e IEnumerable.
No acepte esto como respuesta.
Estoy repitiendo lo que workmad3 dijo arriba.
Al implementarlo en ArrayList, es fácil saberlo, qué interfaces ArrayList implementa en lugar de ir a IList para encontrar que implementa ICollection e IEnumerable.
Eso evita la necesidad de ir y venir de 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 e IEnumerable también. Por lo tanto, 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 e IEnumerable.
Y el razonamiento de workmad3 tiene sentido.
Solo estoy adivinando, pero creo que en realidad solo implementa IList en el código, pero la documentación muestra el resto de las interfaces también para hacerlo explícito al programador que usa la clase.