How can I implement NotOfType<T> in LINQ that has a nice calling syntax?
I am not sure why you don't just say:
animals.Where(x => !(x is Giraffe));
This seems perfectly readable to me. It is certainly more straight-forward to me than animals.NotOfType<Animal, Giraffe>()
which would confuse me if I came across it... the first would never confuse me since it is immediately readable.
If you wanted a fluent interface, I suppose you could also do something like this with an extension method predicate on Object
:
animals.Where(x => x.NotOfType<Giraffe>())
How about
animals.NotOf(typeof(Giraffe));
Alternatively, you can split the generic parameters across two methods:
animals.NotOf().Type<Giraffe>();
public static NotOfHolder<TSource> NotOf<TSource>(this IEnumerable<TSource> source);
public class NotOfHolder<TSource> : IHideObjectMembers {
public IEnumerable<TSource> NotOf<TNot>();
}
Also, you need to decide whether to also exclude inherited types.
This might seem like a strange suggestion, but what about an extension method on plain old IEnumerable
? This would mirror the signature of OfType<T>
, and it would also eliminate the issue of the redundant <T, TExclude>
type parameters.
I would also argue that if you have a strongly-typed sequence already, there is very little reason for a special NotOfType<T>
method; it seems a lot more potentially useful (in my mind) to exclude a specific type from a sequence of arbitrary type... or let me put it this way: if you're dealing with an IEnumerable<T>
, it's trivial to call Where(x => !(x is T))
; the usefulness of a method like NotOfType<T>
becomes more questionable in this case.