为什么编译器认为这是一个Object而不是DataRow?

时间:2010-08-02 14:40:20

标签: .net vb.net linq casting option-strict

我正在使用LINQ查询将DataTable对象中的数据转换为自定义POCO对象的简单IEnumerable

我的LINQ查询是:

    Dim dtMessages As DataTable

    '...dtMessages is instantiated ByRef in a helper data access routine... '

    Dim qry = From dr As DataRow In dtMessages.Rows
              Select New OutboxMsg With {
                  .ComputerID = dr(dcComputerID),
                  .MessageData = dr(dcMessageData),
                  .OutBoxID = dr(dcOutBoxID),
                  .OutBoxReceivedID = dr(dcOutBoxReceivedID),
                  .TrxDate = dr(dcTrxDate)
              }

但是,编译器在dr As DataRow下面发出一条警告消息,其中包含以下消息:

  

Option Strict On禁止从'Object'到'System.Data.DataRow'的隐式转换。

为什么我会收到此错误,我需要做些什么才能修复它?我原以为dtMessages.Rows返回了DataRow类型的集合。这不正确吗?

3 个答案:

答案 0 :(得分:12)

Lok在DataTable.Rows - 这是一个DataRowCollection,它只实现IEnumerable,而不是IEnumerable(Of DataRow)

幸运的是,DataTableExtensions中有一种扩展方法,可让您拨打AsEnumerable()而不是Rows; AsEnumerable会返回IEnumerable(Of DataRow)

Dim qry = From dr As DataRow In dtMessages.AsEnumerable()
          ...

(我更喜欢使用dt.Rows.Cast(Of DataRow),因为它对可能失败的东西的印象较少。它更适合于DataTable。两者都会有效。 )

答案 1 :(得分:7)

类型System.DataTable早于.Net中的泛型,因此返回普通的IEnumerable而不是IEnumerable(Of DataRow),即使它们是DataRow的实例。因此,上述查询中dr的类型为Object而非DataRow

您可以使用Cast扩展方法解决此问题,以明确显示集合的类型

From dr As DataRow in dtMessages.Rows.Cast(Of DataRow)

答案 2 :(得分:3)

DataTable.Rows属性返回DataRow的集合,但该集合不实现IEnumerable<DataRow>,而IEnumerable实现IEnumerable<Object>

您可以使用DataRow明确地将收藏项目转换为dtMessages.Rows.Cast<DataRow>()