How to Use LINQ on a non-generic IEnumerable

by Larry Spencer Wednesday, April 3, 2013 8:27 AM

An instructive moment came up in a code review this week. A developer was using a TempFileCollection to store -- you guessed it -- the names of some temporary files. TempFileCollection will throw an ArgumentException if you add to it a file name that already exists. If TempFileCollection were an IEnumerable<T>, you could use LINQ to check first, like this:

 

if (!myCollection.Any( f => String.Compare(f, newFile, true) == 0 ))
    myCollection.Add(newFile);

 

(Note that we must do a case-insensitive compare, so LINQ's handy Contains() method is no help.)

However, TempFileCollection is an IEnumerable, but not an IEnumerable<T>. That means you can't use LINQ on it. Do we really have to loop through the colleciton by hand, looking for the existing file? How heartbreaking!

Not so fast! IEnumerable does have an extension method called Cast<T>. As MSDN says, "The Cast<TResult>(IEnumerable) method enables the standard query operators to be invoked on non-generic collections by supplying the necessary type information." In plain English -- I mean, plain code -- that looks like this:

 

if (!myCollection.Cast<string>().Any( f => String.Compare(f, newFile, true) == 0 ))
    myCollection.Add(newFile);

 

So that's how you can make LINQ available even on non-generic IEnumerables!

Tags: , , ,

All | General

Add comment