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

时间:2015-04-23 16:49:44

标签: c# var type-inference

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

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

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

5 个答案:

答案 0 :(得分:6)

您对datagridview.Rows的调用会返回DataGridViewRowCollection类型的实例,该实例会实现非通用 ICollectionIEnumerable和{{1}因此,当你执行“foreach”时,它将返回IList类型的实例。

implicitly typed variableSystem.Object语句一起使用时,var row变量的类型现在将变为row

要解决此问题,您可以在System.Object语句中明确指定row的类型:

foreach

这是有效的,因为foreach (DataGridViewRow row in datagridview.Rows) { row.Visible = false; } 实现以静默方式执行从foreach返回到Enumerator.Current类型的每个对象的显式转换(强制转换),因为您可以阅读{{3} }。

答案 1 :(得分:2)

DataGridView.Rows是一个继承自IEnumerable而不是IEnumerable<T>的集合,因此您需要使用OfType<T>()Cast<T>()将其转换为IEnumerable<T> }在 System.Linq 命名空间下,因此您必须在代码文件中添加using System.Linq

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

或者,如果您不想使用DataGridViewRowCast<T>(),则可以将其转换为OfType<T>()

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

答案 2 :(得分:0)

您必须专门将类型设置为DataGridViewRow。这就是原因:

DataGridView.Rows的类型为DataGridViewSelectedRowCollection。如果我们折射那个类,我们得到这个:

public class DataGridViewSelectedRowCollection : BaseCollection, IList 

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

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

我猜这是来自.Net时代,当时没有泛型。

答案 3 :(得分:0)

试试这个;

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

答案 4 :(得分:0)

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

因此,它为您提供了object而不是DataGridViewRow的序列。

现在形式:

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

...将起作用,因为foreach涉及固有演员。

这在.NET1.0和1.1时代是非常方便的,因为没有泛型,因此不是通用的枚举器。今天它没有那么有用了(特别是因为它意味着一些在运行时无法工作的东西仍然可以编译,没有这种固有的演员可能会被捕获),但它在这里对你有用。

var虽然总是表达式的类型,在本例中是object