为什么C#不能推断出DataTable Row的类型

时间:2018-02-08 10:03:45

标签: c# datatable .net-4.5 c#-6.0

我正在尝试迭代DataTable并从特定列获取值。到目前为止,我只有for循环的Skeleton。

foreach (var row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}

这不像我预期的那样有效。尝试执行row[0]时出现编译器错误,并显示以下消息:"无法将带有[]的索引应用于Object"类型的表达式。但row不应该是对象,而是DataRow

要解决此问题,我将foreach循环更改为以下内容:

foreach (DataRow row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}

为什么这有必要?为什么C#不能推断出row的类型,就像我试图迭代一个string[]一样?

3 个答案:

答案 0 :(得分:17)

  

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

TL; DR:DataTable早于泛型:(

声明

DataTable.Rows返回DataRowCollectionInternalDataCollectionBase来自here。这实现了非通用ICollection接口,这意味着编译器无法仅仅row推断出object的类型。

这不是DataTable特有的 - 任何时候你只有IEnumerable而不是IEnumerable<T>的东西(并且没有更具体的GetEnumerator方法对于编译器使用),推断的迭代元素类型只是object。在foreach循环中为变量指定显式类型时,编译器会以静默方式为您插入强制转换。

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

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

答案 1 :(得分:9)

Rows的{​​{1}}属性是DataTable类型的对象。

DataRowCollection本身继承自实现DataRowCollectionInternalDataCollectionBase的{​​{1}}。

这些集合中包含的数据类型不会比ICollection进一步指定,因此无法推断到IEnumerable类。

请参阅{{3}}以供参考。

答案 2 :(得分:-3)

原因是行user.addressCannot set property 'residentialAddress' of undefined而非DataRowCollection,其中T为DataRow。