var 不适用于 DataGridViewRow

var won't work with DataGridViewRow

我是 C# 新手,对 "var"

的使用有疑问

当我使用以下代码时一切正常

foreach(DataGridViewRow row in myGrid.Rows)
{
    if (row.Cells[2].Value.ToString().Contains("51000"))
    {
        row.Cells[0].Value = "X";
    }
}

但是当我将 DataGridViewRow 更改为 var 时,我收到错误消息

'object' does not contain definition for 'Cells' and no extension method 'Cells' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)

DataGridViewRow.Rows 是类型 DataGridViewRowCollection,它不实现 IEnumerable<DataGridViewRow>,只实现 IEnumerable。当您没有为 row

指定转换为 DataGridViewRow 时,object 是编译器可以推断出的最佳猜测

因为 GridView.Rows 属性 returns 是 GridViewRowCollection 类型。

在这种情况下,var 无法从用法推断出该对象将是一个 DataGridViewRow 内部。

来源:GridView.Rows Property

myGrid.Rows is of type DataGridViewRowCollection.

这个东西很老了,它的定义是:

public class DataGridViewRowCollection : ICollection, IEnumerable, IList

你看到非通用接口了吗?这个 class 可以实现 IList<DataGridViewRow> 然后 var 就可以工作,但它是遗留的。

IEnumerable 不传递关于项目类型的信息,GetEnumerator 函数在这里没有帮助,因为它 return 是一个 IEnumerator,虽然它可以return 一个 IEnumerator<DataGridViewRow>.

本质上,C# 编译器查找 GetEnumerator 函数,该函数 return 是一个具有 MoveNext 函数和 Current 属性 的对象( 一个 IEnumerable<T>/IEnumerable 接口(当显式实现时)。此 duck-typing approach is for historical reasons, it existed before generics were introduced into the language. The foreach loop variable will be of the same type than the Current property. And within IEnumerator (the non-generic variant), Current 的类型为 object

明确指定类型:

foreach (DataGridViewRow row in myGrid.Rows)
由于缺乏更好的机制,

只是将 Current 的 return 值转换为 DataGridViewRow

如果您真的想在这里使用 var 关键字,您也可以使用 LINQ 来达到同样的效果:

foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())

这行得通,因为枚举数的 Enumerable.Cast<T> extension method returns an IEnumerable<T>, which in turn makes use of IEnumerator<T>, and T ends up as the type of the Current 属性,所以传播了类型信息。

我怀疑此时您是否会从这些详细信息中受益,但您可能希望保留此信息以备日后进一步了解该语言时参考。您必须了解扩展方法和泛型类型才能掌握这一点。

如果将 DataGridViewRow 更改为 Var,C# 不确定是否存在名为单元格的数组。要解决此问题,您可以将 var 转换为 DataGridViewRow,但是如果您知道该类型,使用该类型几乎总是更好,在线查找类型安全以获取更多信息。