2010-05-07 9 views
17

Quando entro questo foreach affermazione ...Perché var valuta su System.Object in "foreach (var row in table.Rows)"?

foreach (var row in table.Rows) 

... la descrizione per var dice class System.Object

Sono confuso perché non è class System.Data.DataRow.

(Nel caso in cui vi state chiedendo, sì, ho using System.Data nella parte superiore del mio file di codice.)


Se io dichiaro il tipo in modo esplicito, come nel ...

foreach (DataRow row in table.Rows) 

... funziona senza errori.


Anche se lo faccio ...

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

... var viene valutato come struct System.Int32. Quindi, il problema non è che var non funzioni in una clausola foreach.


Quindi, c'è qualcosa di strano in DataRowCollection dove gli elementi non valutano automaticamente DataRow. Ma non riesco a capire di cosa si tratta. Qualcuno ha una spiegazione?


Aggiornamento

Ero veramente indeciso che rispondono a segnare (Codeka e Oliver) ... Alla fine, ho deciso di marcare Codeka di perché risponde veramente mia domanda, ma Oliver risponde alla domanda che avrei dovuto chiedere :)

risposta

17

Questo perché la classe DataRowCollection implementa solo la versione non generica di IEnumerable. Quindi il compilatore non sa quale sia il tipo di variabile.

Inserendo esplicitamente il tipo in là, si dice sostanzialmente al compilatore di generare un cast esplicito da object a DataRow.

Questo è un problema che si ritrova con molte delle raccolte e delle classi aggiunte nei giorni .NET 1.x, prima che i farmaci generici fossero disponibili.

12

Mentre codeka ha ragione, esistono altri metodi per ottenere più convenienza in questo roba DataTable e DataRow.

Con .Net 3.5 è possibile aggiungere il gruppo System.Data.DataSetExtensions.

contiene alcune funzioni di estensione come AsEnumerable(this System.Data.DataTable) o Field<T>(this System.Data.DataRow, int) con essa si può chiamare all'interno di un ciclo foreach e gettato la colonna direttamente nel tipo corretto:

int columnIndex = 2; 

foreach(var row in MyDataTable.AsEnumerable()) 
{ 
    var content = row.Field<double>(columnIndex); 
} 
+0

grande punto! +1 –

+0

Ama questa risposta. +1 – wonea