I am trying to iterate over a DataTable and get the values from a particular column. So far I just have the Skeleton of the for loop.
foreach (var row in currentTable.Rows)
{
var valueAtCurrentRow = row[0];
}
This does not work as I expected. I get an compiler error when trying to do row[0]
, with the message: "Cannot apply indexing with [] to an expression of type Object". But row
should not be an object, it is a DataRow
.
To fix this I changed the foreach loop to the following:
foreach (DataRow row in currentTable.Rows)
{
var valueAtCurrentRow = row[0];
}
Why is this necessary? Why can't C# infer the type of row
as it would if I was trying to iterate over a string[]
for example?
Why can't C# infer the type of row as it would if I was trying to iterate over a string[] for example?
TL;DR: DataTable
predates generics :(
DataTable.Rows
is declared to return DataRowCollection
, which derives from InternalDataCollectionBase
. That implements the non-generic ICollection
interface, which means that the compiler can't infer the type of row
beyond just object
.
This isn't specific to DataTable
- any time you have something that only implements IEnumerable
rather than IEnumerable<T>
(and doesn't have a more specific GetEnumerator
method for the compiler to use), the inferred iteration element type is just object
. When you specify an explicit type for the variable in the foreach
loop, the compiler silently inserts a cast for you.
I'd keep the change exactly as you've got it, but an alternative would be to use the Cast
LINQ method:
foreach (var row in currentTable.Rows.Cast<DataRow>())
{
var valueAtCurrentRow = row[0];
}
See more on this question at Stackoverflow