var不适用于DataGridViewRow

Joa*_*uin 20 .net c# var datagridviewrow

我是C#的新手并对使用"var"有疑问

当我使用以下代码时,一切都很好

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

但是,当我改变DataGridViewRowvar我得到和错误的状态

'object'不包含'Cells'的定义,也没有扩展方法'Cells'可以找到接受'object'类型的第一个参数(你是否缺少using指令或汇编引用?)

Luc*_*ski 28

myGrid.Rows是类型的DataGridViewRowCollection.

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

public class DataGridViewRowCollection : ICollection, IEnumerable, IList
Run Code Online (Sandbox Code Playgroud)

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

IEnumerable没有传达关于项目类型的信息,并且该GetEnumerator函数在这里没有帮助,因为它返回一个IEnumerator,而它可以返回一个IEnumerator<DataGridViewRow>.

本质上,C#编译器查找一个GetEnumerator函数,该函数返回一个具有MoveNext函数和Current属性的对象(显式实现时的IEnumerable<T>/ IEnumerable接口).这种鸭子打字方法是出于历史原因,它在将泛​​型引入语言之前就存在了.该foreach循环变量将是相同的类型比的Current特性.在IEnumerator(非通用变体)中,Current属于类型object.

明确指定类型:

foreach (DataGridViewRow row in myGrid.Rows)
Run Code Online (Sandbox Code Playgroud)

简单地将返回值转换Current为a DataGridViewRow,因为缺少更好的机制.

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

foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为扩展方法返回一个,它反过来使用,并最终作为枚举器属性的类型,因此传播类型信息.Enumerable.Cast<T> IEnumerable<T>IEnumerator<T>TCurrent

我怀疑你在这一点上会从这些细节受益,但是当你将了解更多有关该语言的内容时,你可能希望将其保留下来以供进一步参考.您必须了解扩展方法和泛型类型才能掌握这一点.


Vit*_*ova 13

这是因为GridView.Rows属性返回一个GridViewRowCollection类型.

在这种情况下var,不能从使用中推断该对象将是一个DataGridViewRow内部.

来源:GridView.Rows属性


ASh*_*ASh 5

DataGridViewRow.Rows是类型的DataGridViewRowCollection,它没有实现IEnumerable<DataGridViewRow>而已,IEnumerable.而且object是编译器可以推断,当你不指定投给最好的猜测DataGridViewRowrow