“var” C# 中的类型推断
可能的重复:
为什么 var 求值到“foreach(table.Rows 中的 var row)”中的 System.Object?
今天我很惊讶地发现了以下内容......
SqlDataReader reader = cmd.ExecuteReader();
DataTable schemaTable = reader.GetSchemaTable();
// the following compiles correctly
foreach (DataRow field in schemaTable.Rows)
{
Console.WriteLine(field["ColumnName"]);
}
// the following does not compile as 'var' is of type 'object'
foreach (var field in schemaTable.Rows)
{
// Error: Cannot apply indexing with [] to an expression of type 'object'
Console.WriteLine(field["ColumnName"]);
}
这里发生了什么事?
这是类型推断失败吗?如果是这样,是什么原因造成的?
或者它是定义行为或 var
的一部分?如果是这样,为什么?
我认为 var
的想法是,您可以在变量声明/初始化中的任何地方使用它,而不改变行为。
Possible Duplicate:
Why does var evaluate to System.Object in “foreach (var row in table.Rows)”?
I was rather suprised to discovered the following today....
SqlDataReader reader = cmd.ExecuteReader();
DataTable schemaTable = reader.GetSchemaTable();
// the following compiles correctly
foreach (DataRow field in schemaTable.Rows)
{
Console.WriteLine(field["ColumnName"]);
}
// the following does not compile as 'var' is of type 'object'
foreach (var field in schemaTable.Rows)
{
// Error: Cannot apply indexing with [] to an expression of type 'object'
Console.WriteLine(field["ColumnName"]);
}
Whats going on here?
Is this a type inference failure? And if so, what causes it?
Or is it part of the defined behaviour or var
? And if so, why?
I thought the idea of var
was that you could use it anywhere in a variable declaration/initialisation without changing behaviour.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这里的重点不是var,而是foreach循环。除了迭代自身之外,foreach 循环还可以选择强制转换迭代器。
因此,您可以执行以下操作:
因此,即使列表的类型为 object,它也可以在 foreach 内动态转换为 int。
The point here is not var, but the foreach loop. The foreach loop can optionally cast the iterator in addition to iterating itself.
So you can do the following:
So even if the list is of type object, it can be casted to int on the fly inside the foreach.
DataTable.Rows
返回System.Data.DataRowCollection
,它是InternalDataCollectionBase
的子类。GetEnumerator
方法返回IEnumerator
,而不是IEnumerator
。因此,唯一可用的类型信息是它返回
object
,因此当您指定枚举DataRow
时,您将添加自己的强制转换,其中var
没有。DataTable.Rows
returnsSystem.Data.DataRowCollection
which is a subclass ofInternalDataCollectionBase
.The
GetEnumerator
memthod on this returnsIEnumerator
, rather thanIEnumerator<DataRows>
.Hence the only type information available is that it returns
object
, so when you specify you are enumeratingDataRow
you are adding your own cast, whichvar
does not.令人困惑的是, foreach(SomeType thing in SomeCollection) 不仅遍历集合,它还在迭代时尝试将每个项目强制转换为 SomeType。但对于 var 来说,没有什么可以投射的。
The confusion is that
foreach(SomeType thing in SomeCollection)
doesn't just iterate through the collection, it also attempts a cast to SomeType for each item as it iterates. But with var there's nothing to cast to.