Estoy intentando crear una implementación para NotOfType
, que tiene una sintaxis de llamada legible. NotOfType
debe ser el complemento a OfType<T>
y sería por lo tanto producir todos los elementos que son no de tipo T
¿Cómo puedo implementar NotOfType <T> en LINQ que tiene una buena sintaxis de llamadas?
Mi objetivo era poner en práctica un método que se llama igual que OfType<T>
, al igual que en la última línea de este fragmento:
public abstract class Animal {}
public class Monkey : Animal {}
public class Giraffe : Animal {}
public class Lion : Animal {}
var monkey = new Monkey();
var giraffe = new Giraffe();
var lion = new Lion();
IEnumerable<Animal> animals = new Animal[] { monkey, giraffe, lion };
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Giraffe>();
Sin embargo, no puedo encontrar una implementación que admita esa sintaxis de llamada específica.
Esto es lo que he probado hasta ahora:
public static class EnumerableExtensions
{
public static IEnumerable<T> NotOfType<T>(this IEnumerable<T> sequence, Type type)
{
return sequence.Where(x => x.GetType() != type);
}
public static IEnumerable<T> NotOfType<T, TExclude>(this IEnumerable<T> sequence)
{
return sequence.Where(x => !(x is TExclude));
}
}
llamar a estos métodos se vería así:
// Animal is inferred
IEnumerable<Animal> fewerAnimals = animals.NotOfType(typeof(Giraffe));
y
// Not all types could be inferred, so I have to state all types explicitly
IEnumerable<Animal> fewerAnimals = animals.NotOfType<Animal, Giraffe>();
Creo que hay grandes inconvenientes con el estilo de ambas llamadas. El primero sufre de una construcción redundante de "tipo/tipo de", y el segundo simplemente no tiene sentido (¿quiero una lista de animales que no son ni animales ni jirafas?).
Entonces, ¿hay alguna manera de lograr lo que quiero? Si no, ¿podría ser posible en futuras versiones del lenguaje? (Estoy pensando que tal vez algún día tengamos argumentos de tipo con nombre, o que solo necesitemos proporcionar explícitamente argumentos de tipo que no se puedan inferir?)
¿O solo estoy siendo tonto?
sólo escribir marco/código compartido como éste si siento que va a obtener una buena cantidad de reutilización. ¿Con qué frecuencia necesita un método como este y justifica el costo (tiempo dedicado a pensar en las dificultades de diseño)? –
Sus dos versiones hacen cosas sustancialmente diferentes. – SLaks
@SLaks: Elaborar, por favor. –