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
内部。
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,但是如果您知道该类型,使用该类型几乎总是更好,在线查找类型安全以获取更多信息。
我是 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
内部。
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,但是如果您知道该类型,使用该类型几乎总是更好,在线查找类型安全以获取更多信息。