4

这个问题是“LINQ cast with a Data.DataTableCollection”的连续问题,这里是链接 [question] LINQ cast with a Data.DataTableCollection @Lasse Espeholt

我遇到同样的情况。我想对集合 DataTableCollection 进行 LINQ 查询。但是,如果我写下以下代码:

from dataTable in dataSet.Tables

Visual Studio 会报错“找不到源类型'System.Data.DataTableCollection'的查询模式的实现”。所以解决方案是将代码更改为以下内容:

from dataTable in dataSet.Tables.Cast<DataTable> ()

所以我从互联网上挖掘了根本原因。我发现了一些线索,“一个典型的 LINQ to Objects 查询表达式不仅将一个实现 IEnumerable 的类作为其数据源,而且它还返回一个相同类型的实例。” 在这个页面中。所以我想知道DataTableCollection 不继承IEnumerable 接口。但是根据我查看MSDN,我发现DataTableCollection的继承关系如下:

DataTableCollection
    InternalDataCollectionBase
        ICollection
            IEnumerable

所以这种继承关系意味着DataTableCollection只继承接口IEnumerable,不继承接口IEnumerable。所以它不能支持 LINQ 查询。解决方案是使用 cast 方法转换为 IEnumerable 然后可以进行 LINQ 查询。

所以我总结为想要启用LINQ to object的功能的类,它必须继承接口IEnumerable和IEnumerable。

我的总结对吗?IEnumerable 和 IEnumerable 有什么区别?

4

1 回答 1

11

这里的问题是DataTableCollection没有实现通用IEnumerable<T>接口。IEnumerable这个接口是在 .NET 2.0 中添加的,它继承自早期的非通用接口。LINQ 查询需要这个通用接口,并且不适用于非通用版本。

DataTableCollection是一个在 2.0 之前可用的类,而泛型IEnumerable<T>是在 .NET 2.0 中添加的。

尽管微软本可以在现有框架类型上添加这个通用接口,但我的猜测是,由于时间限制、风险和有用性有限,他们没有这样做。

有很多旧的类可以从拥有这个通用接口中受益(有时它们缺少那个接口很烦人),但是添加这个需要很多时间来实现和测试向后兼容性。更改现有内容包括破坏现有应用程序的风险。.NET 设计人员对于引入重大更改非常保守。

所以我认为他们计算出的成本高于收益,因为在新工具可用的未来,这些旧类型将不会被使用那么多。Enumerable.Cast<T>(Enumerable)此外,您已经找到了扩展方法形式的简单解决方法。

C# LINQ 语言实现甚至内置了对这种Cast<T>方法的支持;可以写成如下:

from DataTable dataTable in dataSet.Tables

在封面下翻译为:

from dataTable in dataSet.Tables.Cast<DataTable>()
于 2013-05-29T05:14:19.480 回答