编译器未在 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
, IEnumerable
和 IList
接口,因此,当您执行 "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.Rows
是 DataGridViewSelectedRowCollection
类型。如果我们折射 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
.
在以下代码中,row
被视为 object
而不是 DataGridViewRow
。
foreach (var row in datagridview.Rows)
{
row.Visible = false //<- error because no Visible property
}
我错过了什么吗?行不应该是 DataGridViewRow
?
您对 datagridview.Rows
return 的调用是类型 DataGridViewRowCollection
的一个实例,它实现了 非泛型 ICollection
, IEnumerable
和 IList
接口,因此,当您执行 "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.Rows
是 DataGridViewSelectedRowCollection
类型。如果我们折射 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>()
:
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
.