Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does var evaluate to System.Object in "foreach (var row in table.Rows)"?

Tags:

c#

ado.net

When I enter this foreach statement...

foreach (var row in table.Rows)

...the tooltip for var says class System.Object

I'm confused why it's not class System.Data.DataRow.

(In case you're wondering, yes, I have using System.Data at the top of my code file.)


If I declare the type explicitly, as in...

foreach (DataRow row in table.Rows)

...it works fine with no errors.


Also if I do...

var numbers = new int[] { 1, 2, 3 };
foreach (var number in numbers)

...var evaluates to struct System.Int32. So, the problem is not that var doesn't work in a foreach clause.


So, there's something strange about DataRowCollection where the items don't automatically evaluate to DataRow. But I can't figure out what it is. Does anyone have an explanation?


Update

I was really torn which answer to mark (Codeka and Oliver)...In the end, I decided to mark Codeka's because it truly answers my question, but Oliver answers the question I should have been asking :)

like image 658
devuxer Avatar asked May 07 '10 06:05

devuxer


2 Answers

That's because the DataRowCollection class only implements the non-generic version of IEnumerable. So the compiler doesn't know what the type of the variable is.

By explicitly putting the type in there, you basically tell the compiler to generate an explicit cast from object to DataRow.

This is a problem you'll find with many of the collections and classes added back in the .NET 1.x days, before generics were available.

like image 165
Dean Harding Avatar answered Nov 03 '22 02:11

Dean Harding


While codeka is right, there exists some other methods to get more convenience into this DataTable and DataRowstuff.

With .Net 3.5 you can add the assembly System.Data.DataSetExtensions.

It contains some extension functions like AsEnumerable(this System.Data.DataTable) or Field<T>(this System.Data.DataRow, int) with it you can call it within a foreach loop and cast the column directly into the proper type:

int columnIndex = 2;

foreach(var row in MyDataTable.AsEnumerable())
{
    var content = row.Field<double>(columnIndex);
}
like image 28
Oliver Avatar answered Nov 03 '22 03:11

Oliver