为什么可以';tc#推断数据表行的类型

为什么可以';tc#推断数据表行的类型,c#,datatable,.net-4.5,c#-6.0,C#,Datatable,.net 4.5,C# 6.0,我试图迭代一个DataTable并从特定列中获取值。到目前为止,我只有for循环的骨架 foreach (var row in currentTable.Rows) { var valueAtCurrentRow = row[0]; } 这并不像我预期的那样有效。我在尝试执行行[0]时遇到一个编译器错误,消息是:“无法将带[]的索引应用于Object类型的表达式”。但是行不应该是对象,它是数据行 为了解决这个问题,我将foreach循环更改为以下内容: foreach (DataRow

我试图迭代一个DataTable并从特定列中获取值。到目前为止,我只有for循环的骨架

foreach (var row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}
这并不像我预期的那样有效。我在尝试执行
行[0]
时遇到一个编译器错误,消息是:“无法将带[]的索引应用于Object类型的表达式”。但是
不应该是对象,它是
数据行

为了解决这个问题,我将foreach循环更改为以下内容:

foreach (DataRow row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}
为什么这是必要的?为什么C#不能推断出
行的类型
,就像我试图迭代一个
字符串[]
那样

为什么C#不能像我尝试迭代字符串[]时那样推断行的类型

TL;DR:
DataTable
早于泛型:(

声明为返回,它派生自。它实现了非泛型的
ICollection
接口,这意味着编译器不能推断出
行的类型,而只能推断
对象

这并不特定于
DataTable
——只要您有一些只实现
IEnumerable
而不是
IEnumerable
(并且没有更具体的
GetEnumerator
方法供编译器使用),推断的迭代元素类型只是
对象
。当您在
foreach
循环中为变量指定显式类型时,编译器会自动为您插入强制转换

我会按照您的要求保留更改,但另一种方法是使用
Cast
LINQ方法:

foreach (var row in currentTable.Rows.Cast<DataRow>())
{
   var valueAtCurrentRow = row[0];
}
foreach(currentTable.Rows.Cast()中的var行)
{
var valueAtCurrentRow=行[0];
}

数据表的
属性是
数据行集合
类型的对象

DataRowCollection
本身继承自
InternalDataCollectionBase
,后者实现了
ICollection
IEnumerable

这些集合中包含的数据类型没有比
对象
进一步指定,因此无法将其推断为
数据行


请参阅以供参考。

原因是Rows is
DataRowCollection
IEnumerable
,而不是
IEnumerable
,其中T是DataRow。

这似乎是因为
Rows
属性公开了一个
DataRowCollection
,它是IEnumerable,但不是IEnumerable,这意味着枚举数在g这与枚举
对象的集合相同,这意味着强制转换是必要的。这就是为什么
数据表
大多数人都不赞成…当你可以使用
数据表
@CamiloTerevinto时,不幸的是,我正在处理一个遗留系统,我别无选择,只能使用已有的。@CamiloTerevinto我从未见过er听说了
DataTable
,谷歌搜索也没有透露任何信息。你能给我一个你在说什么的链接吗?@UweKeim看,这是
DataSet
,在读这篇文章之前,我使用了OfType而不是使用Cast,主要是在DataGridView上。当我需要迭代EDS修订时,行或相似性不会让我感到惊讶IEnumberable中的nse.Typo?很抱歉,我这边的输入错误没有显示出来