Bookmark and Share

What’s the deal with AsEnumerable?

There’s an odd LINQ method that appears to do nothing but is actually quite useful: AsEnumerable().

Declarations

When using LINQ in C#, we typically use the var keyword as it beats typing IEnumerable<Product>. Besides, do you really care where you end up? The important thing is you have a variable that tells you what your sequence is. If I have “var products” on the left side of the assignment, I know I have a sequence of products, and that’s what is important.

There is a small danger in using the var keyword. Some LINQ functions that return a sequence don’t return IEnumerable<T> but instead return a specialized version. OrderBy returns IOrderedEnumerable<T>, and this can cause you problems if you need to reassign the variable.

var products = context.Products.OrderBy(p => p.Category);

if (!productName.IsNullOrEmpty())
{
    products = products.Where(p => p.Name.Contains(productName));
}

The products variable cannot be assigned in the example above because Where returns IEnumerable<T>, but products has been declared as IOrderedEnumerable<T>. The principle, program to the interface, not the implementation applies, and the AsEnumerable will still allow you to use the var keyword.

var products = context.Products.OrderBy(p => p.Category).AsEnumerable();

if (!productName.IsNullOrEmpty())
{
    products = products.Where(p => p.Name.Contains(productName));
}

Adding .AsEnumerable() after the OrderBy fixes the problem.

Escape Custom LINQ Implementations

Sometimes people have implemented the standard extension methods on their on enumerations. Even worst, sometimes people’s own enumerable classes are inherited from List<T>.

public class ProductList : List<Product>
{
    public IEnumerable<Product> Where(Func<Product, bool> predicate)
    {
        Console.WriteLine("Got Here");
        foreach (var product in this)
        {
            if (predicate(product))
            {
                yield return product;
            }
        }
    }
}

Here’s the code to call this.

var products = productList
                    .Where(p => p.Name.Contains(productName))
                    .ToArray();

This writes “Got Here” to the Console.

var products = productList
                    .AsEnumerable()
                    .Where(p => p.Name.Contains(productName))
                    .ToArray();

Adding AsEnumerable() causes Enumerable.Where to be call, and nothing will be written to the Console.

AsEnumerable is also great if you want to break out of a Queryable and do the processing in memory rather than on a server. It’s a nice tool to have for any C# developer.

blog comments powered by Disqus

KodefuGuru.GetInfo()

Chris Eargle
LinkedIn Twitter Technorati Facebook

Chris Eargle
Telerik Developer Evangelist, C# MVP

JustCode

Telerik .NET Ninja

 

INETA Community Speakers Program

 

MVP - Visual C#

 

Friend of RedGate

World Map

Tag cloud

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.