Why C # Cannot Derive DataTable String Type

I am trying to iterate over a DataTable and get values ​​from a specific column. So far I have a for loop skeleton.

foreach (var row in currentTable.Rows) { var valueAtCurrentRow = row[0]; } 

This does not work as I expected. I get a compiler error when I try to make row[0] , with the message: "Cannot apply indexing from [] 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 row , as if I were trying to iterate over string[] , for example?

+8
c # datatable
source share
3 answers

Why can't C # output the string type as if I were trying to iterate over the string [], for example?

TL; DR: DataTable precedes generics :(

DataTable.Rows declared as a returned DataRowCollection , which derives from InternalDataCollectionBase . This implements a non-generic ICollection interface, which means that the compiler cannot infer the type of row outside of just the object .

This does not apply to a DataTable - whenever you have something that implements only IEnumerable and not IEnumerable<T> (and does not have a more specific GetEnumerator method for use by the compiler), the Type of the selected iteration type is just an object . When you specify an explicit type for a variable in a foreach , the compiler silently adds you a cast.

I would save the changes exactly as you received it, but the alternative would be to use the Cast LINQ method:

 foreach (var row in currentTable.Rows.Cast<DataRow>()) { var valueAtCurrentRow = row[0]; } 
+16
source share

The Rows property of the DataTable is an object of type DataRowCollection .

DataRowCollection itself inherits from InternalDataCollectionBase , which implements ICollection and IEnumerable .

The data type contained in these collections is no longer defined than Object , so it cannot be inferred for the DataRow class.

See here for reference.

+9
source share

The reason for this is the DataRowCollection String, which is IEnumerable instead of IEnumerable<T> , where T is a DataRow.

-3
source share

All Articles