2011-02-08 24 views
6

Duplicar posibles:
Why does var evaluate to System.Object in “foreach (var row in table.Rows)”?"var" inferencia de tipos en C#

estaba bien sorprendido al descubierto lo siguiente hoy ....

SqlDataReader reader = cmd.ExecuteReader(); 
DataTable schemaTable = reader.GetSchemaTable(); 


// the following compiles correctly 
foreach (DataRow field in schemaTable.Rows) 
{ 
    Console.WriteLine(field["ColumnName"]); 
} 


// the following does not compile as 'var' is of type 'object' 
foreach (var field in schemaTable.Rows) 
{ 
    // Error: Cannot apply indexing with [] to an expression of type 'object' 
    Console.WriteLine(field["ColumnName"]); 
} 

¿Qué está pasando ¿aqui?

¿Esto es un error de inferencia de tipo? Y si es así, ¿qué lo causa?

¿O es parte del comportamiento definido o var? Y si es así, ¿por qué?

Pensé que la idea de var era que se podía usar en cualquier lugar en una declaración de variable/inicialización sin cambiar el comportamiento.

+1

'DataRowCollection.GetEnumerator()' devuelve 'IEnumerator'. El tipo de 'IEnumerator.Current' es' object'. –

+0

[pregunta duplicada exacta] (http://stackoverflow.com/questions/2325777/why-cant-i-do-foreach-var-item-in-datatable-rows) Basically Rows es un 'DataRowCollection', por lo que el compilador toma 'Object', no' DataRow' – Axarydax

Respuesta

3

El punto aquí no es var, sino el bucle foreach. El ciclo foreach opcionalmente puede convertir el iterador además de iterarse a sí mismo.

para que pueda hacer lo siguiente:

List<object> test = new List<object>(); 
test.Add(1); 
test.Add(2); 
test.Add(3); 
foreach(int i in test){ 
    i.Dump(); 
} 

Así que incluso si la lista es de tipo de objeto, que puede lanzar a int sobre la marcha dentro del foreach.

+0

No lo sabía, gracias. Me preguntaba por qué el iterador no requería un molde explícito en el primer ejemplo. – fearofawhackplanet

+0

Tenga en cuenta que si hace esto, obtendrá una excepción de referencia nula si el tipo a la izquierda del nombre de la variable no coincide con el tipo real del objeto en la enumeración. No puede usarlo para ir a 'foreach (DerivedType derived in ListOfBaseTypes)' y esperar que funcione correctamente a menos que todo en su 'ListOfBaseTypes' sea de tipo' DerivedType' – Stephen

0

La confusión es que foreach(SomeType thing in SomeCollection) no se limita a recorrer la colección, sino que también intenta un yeso para SomeType para cada elemento, ya que itera. Pero con var no hay nada a lo que echarle.

1

DataTable.Rows devuelve System.Data.DataRowCollection que es una subclase de InternalDataCollectionBase.

El elemento GetEnumerator en esto devuelve IEnumerator, en lugar de IEnumerator<DataRows>.

Por lo tanto, el único tipo de información disponible es que devuelve object, por lo que cuando especifica que está enumerando DataRow está agregando su propio modelo, que var no lo hace.

Cuestiones relacionadas