编译器未在 visual studio 中使用 var 关键字检测类型

compiler not detecting type using var keyword in visual studio

在以下代码中,row 被视为 object 而不是 DataGridViewRow

foreach (var row in datagridview.Rows)
{
   row.Visible = false  //<- error because no Visible property
}

我错过了什么吗?行不应该是 DataGridViewRow?

您对 datagridview.Rows return 的调用是类型 DataGridViewRowCollection 的一个实例,它实现了 非泛型 ICollection , IEnumerableIList 接口,因此,当您执行 "foreach" 时,它将 return 类型 System.Object.

的实例

var row 语句中使用 implicitly typed variable 时,row 变量的类型现在将变为 System.Object

要解决这个问题,您可以在 foreach 语句中明确指定 row 的类型:

foreach (DataGridViewRow row in datagridview.Rows)
{
   row.Visible = false;
}

这是有效的,因为 foreach 实现默默地执行每个对象的显式转换(转换)return 从 Enumerator.Current 到类型 DataGridViewRow,因为你可以阅读 here.

您必须专门将类型设置为 DataGridViewRow。原因如下:

DataGridView.RowsDataGridViewSelectedRowCollection 类型。如果我们折射 class,我们会得到:

public class DataGridViewSelectedRowCollection : BaseCollection, IList 

从未指定类型,没有使用泛型,只是普通的旧集合。

因此,.net 无法自动推断类型。您必须专门将类型设置为 DataGridViewRow。

我猜这是从 .Net 时代开始的,那时还没有泛型。

DataGridView.Rows is a collection which inherits from IEnumerable not IEnumerable<T> so you will need to use OfType<T>() or Cast<T>() 将其转换为 System.Linq 命名空间下的 IEnumerable<T>,因此您必须在其中添加 using System.Linq您的代码文件:

foreach (var row in datagridview.Rows.OfType<DataGridViewRow)
{
   row.Visible = false  //<- error because no Visible property
}

或者如果你不想使用 Cast<T>()OfType<T>():

,你可以在 foreach 中将其转换为 DataGridViewRow
foreach (DataGridView row in datagridview.Rows)
{
   row.Visible = false  //<- error because no Visible property
}

试试这个;

for(var i =0;i< datagridview.Rows.Count;i++)
{ var row = datagridview.Rows[i];
   row.Visible = false  
}

DataGridViewRowCollection 实现 IEnumerable 但不实现 IEnumerable<DataGridViewRow>

因此,它为您提供了 object 而不是 DataGridViewRow.

的序列

现在的形式:

foreach(DataGridViewRow row in datagridview.Rows)
{
   row.Visible = false;
}

... 会起作用,因为 foreach 涉及固有转换。

这在 .NET1.0 和 1.1 时代非常方便,当时没有泛型,因此也没有泛型枚举器。今天它没有以前那么有用了(特别是因为它意味着一些在运行时无法运行的东西仍然可以编译,如果没有这种固有的强制转换就可以被捕获),但它在这里对你有用。

var 虽然始终是表达式的类型,在本例中为 object.