c# - ¿Por qué `IList<T>` no hereda de `IReadOnlyList<T>`?
.net generics (1)
@wb puso un enlace a social.msdn.microsoft.com/Forums/vstudio/en-US/… en los comentarios que contienen una respuesta:
¿Por qué no cambiamos las interfaces existentes para ampliar las interfaces de solo lectura?
Parece una suposición razonable de que funciona porque las interfaces de solo lectura son simplemente un subconjunto de las interfaces de lectura-escritura. Desafortunadamente, es incompatible porque a nivel de metadatos cada método en cada interfaz tiene su propia ranura (lo que hace que las implementaciones explícitas de la interfaz funcionen).
Immo Landwerth | .NET Framework Team (BCL) | http://blogs.msdn.com/b/bclteam/
Para explicar esto un poco más claro:
Supongamos que un programa escrito para .NET 4.0 contiene una clase MyList<T>
que implementa IList<T>
. Claramente, no puede implementar IReadOnlyList<T>
ya que esa interfaz no existe.
Ahora suponga que el administrador del sistema instala .NET 4.5 y suponga que .NET 4.5 hizo que IList<T>
implementara IReadOnlyList<T>
.
Si el programa se cargara, el tiempo de ejecución detectaría que MyList<T>
pretende implementar IList<T>
, pero en realidad no implementa todos los métodos: no implementa los métodos de IReadOnlyList<T>
. El programa ya no funcionaría.
El compilador de C # podría ser capaz de hacer coincidir los métodos por nombre, pero el tiempo de ejecución no hace esto. Dado que se suponía que .NET 4.5 tenía compatibilidad binaria hacia atrás, las interfaces no podían extenderse para implementar otras interfaces, ni siquiera si esas otras interfaces contienen un subconjunto estricto de los métodos requeridos.
Cuando se IReadOnlyList<T>
en .NET 4.5, por un momento pensé que la parte faltante del rompecabezas finalmente se insertó en su lugar: una forma de pasar una verdadera interfaz de solo lectura indexable donde antes tendría que usar mi propia lectura. Interfaces y crear clases de envoltura alrededor de todo.
Esperaba que la interfaz se colocara dentro de la jerarquía "natural", que idealmente sería:
IEnumerable<T>
.GetEnumerator()
-> IReadOnlyCollection<T> : IEnumerable<T>
.Count
-> IReadOnlyList<T> : IReadOnlyCollection<T>
.Item[...]
-> IList<T> : IReadOnlyList<T>
.Add(...)
.Clear()
.Contains(...)
(etc)
Pero, como resultado, IList<T>
no hereda de IReadOnlyList<T>
.
¿Hay alguna razón para esto?