Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Comercial
    • Calculadora

0

106
Vistas
Why doesn't IList<T> only inherit from ICollection<T>?

Interestingly, when I go to the definition of IList<T> in the Visual Studio, it's not the same as the source code on GitHub.

enter image description here

IList<T>

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable

ICollection<T>

public interface ICollection<T> : IEnumerable<T>, IEnumerable

Given that ICollection<T> already includes IEnumerable<T> and IEnumerable why does IList<T> need to include them. Couldn't it be simplified as below?

public interface IList<T> : ICollection<T>

I'm trying to understand a logic behind this long interface chaining.

You can check the source code below to see the differences.

https://github.com/microsoft/referencesource/blob/5697c29004a34d80acdaf5742d7e699022c64ecd/mscorlib/system/collections/generic/ilist.cs#L37

10 months ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

TL;DR: The compiler will compile the class as though it specifically implements all mentioned interfaces as well as all implied/inherited interfaces into the assembly. There is no way for ILSpy, ILDasm, or "Go to definition" to know the difference without actually downloading and showing the original source code.


Since you have now clarified that you used Go To Definition in Visual Studio, there are two tools in scope:

  • ILSpy
  • ILDasm

Both takes different approaches to show the contents of a compiled assembly. I believe ILSpy is used behind the scenes in Visual Studio but read on for why that doesn't actually matter.

If we do a simple test in LINQPad:

void Main()
{
}

public interface IA
{
}

public interface IB : IA
{
}

public class Test : IB
{
}

and then ask LINQPad to reflect the code using ILSpy, we get this definition for Test:

public class Test: IB, IA

Clearly ILSpy shows that Test implements both, whereas the source just got IA via IB.

What about ILDasm? I wrote a .NET 5 assembly using Visual Studio, and then decompiled it using ILDasm, with the exact same code as above:

.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
{

Basically, this is an artifact of how the compiler compiles the source. I don't know enough IL to know if reassembling the interface from Intermediate Language, without mentioning IA will actually produce the same output but I'll leave that as an excercise.

I also took a look at various sources for this information:

  1. Reference source does not explicitly list implied interfaces
  2. Github source does not explicitly list implied interfaces
  3. Documentation for IList does not but for IList<T> does
  4. ILSpy decompiles listing all interfaces
  5. ILDasm decompiles listing all interfaces (and this is supposed to be the actual contents so I'd say there is no way to tell the difference at the compiled assembly level)
10 months ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos