Me parece que muchos de los métodos de extensión en IList<T>
son aplicables a IEnumerable<T>
, como FindAll
y RemoveAll
.¿Por qué IEnumerable <T> tiene FindAll o RemoveAll métodos?
¿Alguien puede explicar el razonamiento por qué no están allí?
Me parece que muchos de los métodos de extensión en IList<T>
son aplicables a IEnumerable<T>
, como FindAll
y RemoveAll
.¿Por qué IEnumerable <T> tiene FindAll o RemoveAll métodos?
¿Alguien puede explicar el razonamiento por qué no están allí?
RemoveAll
no tiene sentido ya que no hay Remove
etc en esa API - sin embargo hay es un FindAll
de 3.5 en adelante - pero es conocido como Where
:
IEnumerable<Foo> source = ...
var filtered = source.Where(x => x.IsActive && x.Id = 25);
que es equivalente a:
IEnumerable<Foo> source = ...
var filtered = from x in source
where x.IsActive && x.Id == 25
select x;
Para RemoveAll
no es aplicable en IEnumerable
porque IEnumerable es de solo lectura. Para FindAll
, vea la respuesta de Marc.
Todo IEnumerable
hace es especificar que hay una colección que se puede enumerar o repetir. Ni siquiera especifica que la colección se puede repetir varias veces, y mucho menos manipular. Por lo tanto, cualquier método que manipule la colección no tiene sentido. Los métodos tales como FindAll
tendrían sentido, sin embargo.
Enumerable no implica que haya una colección subyacente, por lo que no puede saber si hay algo que eliminar o no. Si hay es una colección subyacente, no se sabe si es compatible con una operación de eliminación.
Aquí hay un método de ejemplo que enumera los números impares. Si pudieras "eliminar" 7 de enumerable, ¿qué pasaría? ¿De dónde sería eliminado?
public IEnumerable<int> GetOddPositiveNumbers()
{
int i = 0;
while (true)
{
yield return 2*(i++)+1;
}
}
Lo que podría estar buscando es Where
Except
y que le permite filtro de la enumerable.
+1 para el ejemplo. – aboveyou00
Para ser justo, algo como IEnumerable<T>.RemoveAll
puede tener sentido si lo que realmente quiere es una versión de longitud cero de una colección en particular. Llamarlo RemoveAll
NO tiene sentido ya que ninguna implementación de método IEnumerable<T>
debe modificar una colección.
Así que en mi caso a veces uso un método de extensión personalizado que llamo Nil
.
static IEnumerable<T> Nil<T>(this IEnumerable<T> self) {
yield break;
}
En cuanto a FindAll
como ya se ha señalado Marc se llama simplemente Where
.
Gracias por la explicación, veo más de la imagen ahora, pero ¿podría seguir con 2 preguntas relacionadas: (1) ¿por qué la Lista implementa FindAll así como Where, suponiendo que son iguales: (2) ¿Por qué? ICollection no implementa RemoveAll ya que implementa Remove? Gracias Andy –
Andy
@Andy No creo que haya una razón para ello, pero puedes escribir un método de extensión por tu cuenta, mira mi respuesta. –
@Andy 'List' obtiene un 'Donde' porque implementa' IEnumerable '.Re 'ICollection': porque no es una buena idea agregar métodos extra a las interfaces, SIN EMBARGO, sería perfectamente posible implementar eso usando un método de extensión en la interfaz, –