c# - eventos - vb datagridview properties
var no funcionará con DataGridViewRow (4)
Soy nuevo en C # y tengo una pregunta sobre el uso de "var"
Cuando uso el siguiente código, todo funciona muy bien.
foreach(DataGridViewRow row in myGrid.Rows)
{
if (row.Cells[2].Value.ToString().Contains("51000"))
{
row.Cells[0].Value = "X";
}
}
Pero cuando cambio DataGridViewRow
a var
, obtengo un error que dice
''objeto'' no contiene la definición de ''Celdas'' y no se puede encontrar un método de extensión ''Celdas'' que acepten un primer argumento de tipo ''objeto'' (¿falta una directiva de uso o una referencia de ensamblado?)
Es porque la propiedad GridView.Rows
devuelve un tipo GridViewRowCollection
.
En este caso, var
no puede inferir del uso que el objeto será un DataGridViewRow
interior.
Fuente: Propiedad GridView.Rows
Si cambia DataGridViewRow a Var C # no está seguro de que haya una matriz llamada celdas. Para solucionar este problema, puede convertir la var como una DataGridViewRow; sin embargo, casi siempre es mejor usar el tipo si lo conoce, busque en línea de seguridad de tipos para obtener más información.
myGrid.Rows
es de tipo DataGridViewRowCollection
.
Esta cosa es bastante antigua, su definición dice:
public class DataGridViewRowCollection : ICollection, IEnumerable, IList
¿Ves las interfaces no genéricas? Esta clase podría implementar IList<DataGridViewRow>
y luego var
solo funcionaría, pero es heredado.
IEnumerable
no transmite información sobre el tipo de elemento, y la función GetEnumerator
no ayuda aquí, porque devuelve un IEnumerator
, mientras que podría devolver un IEnumerator<DataGridViewRow>
.
Esencialmente, el compilador de C # busca una función GetEnumerator
que devuelve un objeto que tiene una función MoveNext
y una propiedad Current
( o una IEnumerable<T>
/ IEnumerable
cuando se implementa explícitamente). Este enfoque de duck-typing es por razones históricas, existió antes de que se introdujeran los genéricos en el lenguaje. La variable de bucle foreach
será del mismo tipo que la propiedad Current
. Y dentro de IEnumerator
(la variante no genérica), Current
es de tipo object
.
Especificando el tipo explícitamente:
foreach (DataGridViewRow row in myGrid.Rows)
simplemente convierte el valor de retorno de Current
a un DataGridViewRow
, por falta de un mecanismo mejor.
También puede usar LINQ para lograr el mismo efecto, si realmente desea usar esa palabra clave var
aquí:
foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())
Esto funciona, porque el método de extensión Enumerable.Cast<T>
devuelve un IEnumerable<T>
, que a su vez hace uso de IEnumerator<T>
, y T
termina como el tipo de la propiedad Current
del enumerador, por lo que la información de tipo Se propaga.
Dudo que se beneficie de estos detalles en este momento , pero puede querer guardar esto como referencia adicional cuando aprenda más sobre el idioma. Tendría que aprender sobre métodos de extensión y tipos genéricos para comprender esto.
DataGridViewRow.Rows
es de tipo DataGridViewRowCollection , que no implementa IEnumerable<DataGridViewRow>
, solo IEnumerable
. Y el object
es la mejor suposición de qué compilador puede inferir cuando no se especifica la conversión a DataGridViewRow
para la row