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

Mic*_*ock 9 c# datatable .net-4.5 c#-6.0

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

foreach (var row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}
Run Code Online (Sandbox Code Playgroud)

这不像我预期的那样有效.尝试时我收到编译器错误row[0]消息:"无法将[]索引应用于Object类型的表达式".但row不应该是一个对象,它是一个DataRow.

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

foreach (DataRow row in currentTable.Rows)
{
   var valueAtCurrentRow = row[0];
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 18

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

TL; DR:DataTable早于泛型:(

DataTable.Rows声明返回DataRowCollection,来源于InternalDataCollectionBase.实现非泛型ICollection接口,这意味着编译器不能推断的类型row不仅仅是object.

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

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

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


Adw*_*yth 9

所述Rows的属性DataTable是类型的对象DataRowCollection.

DataRowCollection本身继承了InternalDataCollectionBase哪些工具ICollectionIEnumerable.

这些集合中包含的数据类型没有任何进一步指定,Object因此无法推断到DataRow该类.

请参阅此处以供参考.