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

5

我将使用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的集合。这不正确吗?

1
展示如何声明和实例化dtMessages。 - bzlm
@bzlm 我更新了我的帖子,加入了更多信息。 - Ben McCormack
别开启 Option Strict!开玩笑的,开玩笑的。 - Marc
@Marc 他应该关掉VB.NET。 :) - bzlm
尽管我通常更喜欢C#而不是VB.NET,但我得到的报酬是用VB.NET编写代码,所以放弃它将是一个非常昂贵的决定 :-). - Ben McCormack
3个回答

13
看一下DataTable.Rows - 它是一个DataRowCollection,只实现了IEnumerable,而不是IEnumerable(Of DataRow)
幸运的是,在DataTableExtensions中有一个扩展方法,让你调用AsEnumerable()代替RowsAsEnumerable返回一个IEnumerable(Of DataRow)
Dim qry = From dr As DataRow In dtMessages.AsEnumerable()
          ...

我更喜欢使用这种方式,而不是使用dt.Rows.Cast(Of DataRow),因为它给人的印象不太像是可能会失败的事情。它更适合于DataTable。但两种方法都可以使用。


8
类型System.DataTable在.Net中的泛型之前就存在了,因此返回的是普通的IEnumerable而不是IEnumerable(Of DataRow),即使在底层它们都是DataRow的实例。因此,在上面的查询中,dr的类型是Object而不是DataRow
您可以通过使用Cast扩展方法来显式指定集合的类型来解决这个问题。
From dr As DataRow in dtMessages.Rows.Cast(Of DataRow)

3
DataTable.Rows 属性返回一个 DataRow 集合,然而该集合没有实现 IEnumerable<DataRow> 接口,而是实现了 IEnumerable 接口,它作为 IEnumerable<Object> 工作。
您可以使用 dtMessages.Rows.Cast<DataRow>() 将集合项显式转换为 DataRow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接