LINQ in Action - LINQ Book & News

Querying non-generic collections with LINQ to Objects

We will soon publish excerpts of the LINQ in Action book. One of them will probably show you how to query non-generic collections. Before it becomes available, let me show you an overview of what it presents.

When you read and hear about LINQ, you almost always see queries that work on the generic collections provided by the .NET Framework. In fact, you can use LINQ to Objects with any type that implements IEnumerable<T>. This means that LINQ to Objects will work with your own generic collection types or generic collections from other frameworks.

A problem you may encounter is that not all .NET collections actually implement IEnumerable<T>. In fact, only strongly-typed collections implement this interface. Arrays, generic lists and dictionaries are strongly-typed: you can work with an array of integers, a list of strings or a dictionary of Book objects. The non-generic collections do not implement IEnumerable<T>, but implement IEnumerable. Does this mean that you won’t be able to use LINQ with ArrayList or DataSet objects, for example?

Fortunately, solutions exist. In the following code sample, we use Cast<Book> to convert a non-generic ArrayList collection into a typed-collection of Book objects. This allows us to use the Where or Select operators for example:

ArrayList arrayList = new ArrayList();
arrayList.Add(new Book { Title="LINQ in Action" });
arrayList.Add(new Book { Title="LINQ for Fun" });
arrayList.Add(new Book { Title="Extreme LINQ" });

var titles =
  from book in arrayList.Cast<Book>()
  where book.Title.Contains("Action")
  select book.Title;

The Cast operator casts the elements of a source sequence to a given type.
It’s interesting to note that you can also use a feature of C# query expressions. In a C# query expression, an explicitly-typed iteration variable translates to an invocation of Cast. Here how to use Cast transparently by declaring the book iteration variable as a Book:

var titles =
  from Book book in arrayList
  where book.Title.Contains("Action")
  select book.Title;

Stay tuned to learn more in our upcoming excerpts. Of course, you can also get the full book immediately!

Published Saturday, September 15, 2007 7:51 PM by Fabrice Marguerie

Comments

 

Pete said:

Hi!

1. You don't explain what Cast<T>() is. I've never heard of it.

2. Why would anyone use it instead of the standard Linq query operator OfType<T>() ?

September 19, 2007 3:16 PM
 

Pete said:

Ah I see; it's also a standard query operator.

Thanks! I didn't know about it, nor about explicitly typed range variables.

Good luck with your book.

September 19, 2007 3:29 PM
 

Fabrice Marguerie said:

Thanks Pete. I was about to reply :-)

I explain about OfType in the book and in the upcoming excerpt. In two sentences:

The difference between Cast and OfType is that OfType only returns objects from a source collection that are of a certain type. For example, if you have an ArrayList that contains Book and Publisher objects, calling theArrayList.OfType<Book>() returns only the instances of Book from the ArrayList.

September 19, 2007 3:39 PM
New Comments to this post are disabled