Curiosamente, cuando voy a la definición de IList<T>
en Visual Studio, no es lo mismo que el código fuente en GitHub.
IList<T>
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
ICollection<T>
public interface ICollection<T> : IEnumerable<T>, IEnumerable
Dado que ICollection<T>
ya incluye IEnumerable<T>
e IEnumerable
, ¿por qué IList<T>
necesita incluirlos? ¿No podría simplificarse como se muestra a continuación?
public interface IList<T> : ICollection<T>
Estoy tratando de entender una lógica detrás de este largo encadenamiento de interfaz.
Puede consultar el código fuente a continuación para ver las diferencias.
TL; DR : el compilador compilará la clase como si implementara específicamente todas las interfaces mencionadas , así como todas las interfaces implícitas/heredadas en el ensamblaje. No hay forma de que ILSpy, ILDasm o "Ir a definición" sepan la diferencia sin descargar y mostrar el código fuente original.
Como ahora ha aclarado que usó Ir a definición en Visual Studio, hay dos herramientas en el alcance:
Ambos adoptan diferentes enfoques para mostrar el contenido de un ensamblado compilado. Creo que ILSpy se usa detrás de escena en Visual Studio, pero siga leyendo para saber por qué eso en realidad no importa.
Si hacemos una prueba sencilla en LINQPad :
void Main() { } public interface IA { } public interface IB : IA { } public class Test : IB { }
y luego pida a LINQPad que refleje el código usando ILSpy, obtenemos esta definición para Test
:
public class Test: IB, IA
Claramente, ILSpy muestra que Test
implementa ambos, mientras que la fuente acaba de obtener IA
a través de IB
.
¿Qué pasa con ILDasm? Escribí un ensamblado de .NET 5 con Visual Studio y luego lo descompilé con ILDasm, exactamente con el mismo código que el anterior:
.class interface public abstract auto ansi ClassLibrary3.IA { } // end of class ClassLibrary3.IA .class interface public abstract auto ansi ClassLibrary3.IB implements ClassLibrary3.IA { } // end of class ClassLibrary3.IB .class public auto ansi beforefieldinit ClassLibrary3.Test extends [System.Runtime]System.Object implements ClassLibrary3.IB, ClassLibrary3.IA {
Básicamente, este es un artefacto de cómo el compilador compila la fuente. No sé suficiente IL para saber si volver a ensamblar la interfaz desde Intermediate Language, sin mencionar que IA
en realidad producirá el mismo resultado, pero lo dejaré como ejercicio.
También eché un vistazo a varias fuentes para obtener esta información:
IList
no, pero para IList<T>
sí .