C# 3.0 var keyword + Enumerable.AsEnumerable


On my way back from México, I read Pro LINQ: Language Integrated Query in C# 2008. Just like Charles Petzold first introducing WPF through code (and not markup), I like Joseph Rattz’ introduction of LINQ through [extension] methods first instead of the using query expressions. I do think this makes things easier to understand. For me at least. I did not like a big part of the book as it felt more like a reference book. But again, it’s just me.


One thing I disagree with his advice:  page 27, he states that one should refrain from using the var keyword just because it’s convenient. I think that:


var integers = new List<int> { 1, 2, 3 };


is clear enough, no need for:


List<int> integers = new List<int> { 1, 2, 3 };


Also, on page 355, he states that strings will get boxed! Although an immutable type behaving like a value type, System.String is not a value type and will thus never be boxed. I guess he meant that the problem with c[“Id”] == s[“Id”] is that you’re comparing for equality of object reference you’re not comparing the content of the String instances.


Now, one thing I tend to forget when talking to developers is that some are still trying to grasp the idea of generics. And that’s exactly what I thought about when seeing Enumerable.AsEnumerable:


public static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source) {


   return source;


}


 


Why would anyone need to use what looks to be such a useless code method? Look at this query expression:


var query = from dr in orderDataTable.AsEnumerable()


            select dr.Field<int>(“OrderID”);


 


If I’d like to cast OrderTable to a generic version of IEnumerable<T>, what value of T should I pick? In this example, the answer might be easy as DataTableExtensions.AsEnumerable(this DataTable source) returns an EnumerableRowCollection<DataRow> instance: we can cast to IEnumerator<DataRow>.


Both would work:


var query = from dr in (IEnumerable<DataRow>) orderDataTable


            select dr.Field<int>(“OrderID”);


and


var query = from dr in orderDataTable as IEnumerable<DataRow>


            select dr.Field<int>(“OrderID”);


 


But as soon as you have anonymous types involved, doing something like this is impossible: you don’t know the compiler generated name of those types! What would you use as the generic IEnumerable type parameter (you know, the T in IEnumerable<T>)?


The purpose of what looks like the simplistic Enumerable.AsEnumerable() method is hidden in its signature: the compiler will get you the right T to use in IEnumerable<T>, no need to know what it is.


OK. I’m no LINQ expert but by writing this, I’m clarifying my thoughts. I hope this helps.


Bonne nuit les petits.


 

Comments (1)

  1. MSDN Archive says:

    Actually, this is arguably more of a side-effect.

    AsEnumerable is mostly useful for when you want to drop out of using extensions for one type (for example, IQueryable<T> or the DataSetExtensions) and instead start using the IEnumerable extensions.  You’ll note there’s also an AsQueryable method which has similar purpose.

Skip to main content