Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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
- Anonymous
January 10, 2008
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.