views:

32

answers:

1

This doesn't work.

var result = 
    from row in grid.Rows
    where (string) row.Cells["COLUMN_1"].Value == "Test"
    select row.Cells["COLUMN_2"].Value as int?;

But this does.

var result = 
    from row in grid.Rows.Cast<DataGridViewRow>()
    where (string) row.Cells["COLUMN_1"].Value == "Test"
    select row.Cells["COLUMN_2"].Value as int?;

As far as I can tell, the DataGridViewRowCollection is a collection of DataGridViewRows. So why do I have to cast each member to a DataGridViewRow before I can access its properties?

Does it have anything to do with the fact that DataGridViewRowCollection implements the non-generic IEnumerable but not the generic version IEnumerable<DataGridViewRow>? Or that it apparently uses an ArrayList internally? It's not causing me any real problems, but I'd like to understand it better.

+4  A: 

Yes, it's exactly because of the interface it advertises. Almost all the extension methods in LINQ work on IEnumerable<T> rather than IEnumerable. Cast<> is one way of bridging that gap - OfType<> is another.

However, there's a simpler way of calling Cast<T> - just explicitly type your range variable:

var result = 
    from DataGridViewRow row in grid.Rows
    where (string) row.Cells["COLUMN_1"].Value == "Test"
    select row.Cells["COLUMN_2"].Value as int?;

The compiler turns this into exactly the same code as your second sample.

Jon Skeet