(Updated 3/27/2011 and works with .Net 3-4)

When I wrote this article I was fixated on returning IEnumerable instead of of List<>. Being a wiser developer my advice now would be to return IList<> instead of IEnumerable in most situations after using the extension ToList() to not have any differed execution due to IQueryable. One should return IList<> because List<> is malleable and can be changed by the consumer in some situations which may have undesired effects elsewhere. My intent now with this article is just to understand how IQueryable uses IEnumerable, such as does List<> and really when to use IQueryable and how it may effect the code.. To that end I have reworked this article.

IQueryable and IEnumerable and List<>

In .Net 2.0 with the release of generic collections one would return List<> and was not too concerned with IEnumerable which List<> derives from. This changed with .Net 3 and the iQueryable returns.

With Entity Framework and Linq to Object/SQL the ability to build queries (differed execution) was presented to the user. A querable item means that the operation in question is held off until the data values are actually needed. The IEnumerable which List<> and IQueryable inherits from simply provides the common base for operations for items to be enumerated (listed).

Stating again, when one uses or returns IQueryable, the operation of getting the list is not done until the data is actually needed; it is differed.  (One can see that in the Visual Studio debugger when viewing the querable list in question, one has to click on it to enumerate it in the debugger before values are shown! When data is not IQuerable the debugger can show it immediately.)

Whereas wiht List and other IEnumerable derived lists,  such as IList<>, the process is done immediately (unless the parent object is IQueryable then one needs to covert it to a hard List<>). Differed operations are good when building a larger set of data outside the method returing IQueryable. But it is not always needed.

Since the execution is differed changes in the list will be reflected at the time of acquisition. Meaning that if you know the list may change and the user should not see those changes, send back a list and not a Queryable. That is done by calling ToList with any Linq operation.

Original Article

When you find a pattern in programming that is a sign that you need to place it into a function for reuse. With .Net 3.5 there is value in returning IEnumerable of items where before one would return a list.

// Take an object and print out the property name and its value
// for all public properties. public static
void DisplayPublicPropertiesAndValues<T>( T target )
{
   foreach (PropertyInfo prp in GetPublic<T>())
      Console.WriteLine( prp.Name + " " + prp.GetValue( target, null ) );
} 

// I have to put things into a list to enumerate over it in the calling method.
public static List<PropertyInfo> GetPublic<T>()
{
   List<PropertyInfo> retList = new List<PropertyInfo>();     

   foreach (PropertyInfo prp in typeof( T ).GetProperties())
      if (prp.PropertyType == typeof( string ))
         retList.Add( prp );     

   return retList;
}

For example in 2.0 I would have to return a List<> of objects to accommodate my foreach needs such as found in GetPublic when I was reflecting off of a objects instance.

Now we return IEnumerable<> thanks to Linq and let it do the work for you. The above GetPublic in .Net 3.5 looks like this:

public static IEnumerable<PropertyInfo> GetPublicV2<T>()
{
    return (from p in typeof( T ).GetProperties()
           where p.PropertyType == typeof( string )
           select p) // Returns IQueryable
           .ToList();  // Otherwise we would be returning IQueryable so change it to a List to get the data.
}

// Same as above but using the extension methods
public static IEnumerable<PropertyInfo> GetPublicV3<T>()
{
    return typeof( T ).GetProperties()
                      .Where( p => p.PropertyType == typeof( string ))
                      .ToList(); // Otherwise we would be returning IQueryable

}

// As I would actually do it now in 2011
public static IList<PropertyInfo> GetPublicV4<T>()
{
    return typeof( T ).GetProperties()
                      .Where( p => p.PropertyType == typeof( string ) )
                      .ToList(); // Otherwise we would be returning IQueryable

}

A lot nicer. We achieved the same functionality but we don’t have to do the dirty work of creating a List! So advice…get used to working with IEnumerable<>.

Share