浅谈 System.Data.DataRowCollection 类

我们来看看以下程序吧:

01: using System;02: using System.Data;03: using System.Linq;Skyiv.Ben06: {07: class Program08: {09: static void Main()10: {();12: dt.Rows.Add();13: foreach (var row in dt.Select())14: {15: Console.WriteLine(row.GetType());16: Console.WriteLine(row.RowState);17: }18: }19: }20: }

上述程序中第 12 行中的DataTable类的 Rows 属性的类型为DataRowCollection类。第 13 行中的DataTable类的 Select 方法返回DataRow[] 数组。我们知道,foreach语句对实现System.Collections.IEnumerable或System.Collections.Generic.IEnumerable<T>接口的数组或对象集合中的每个元素重复一组嵌入式语句。所以该foreach语句中的 row 变量的类型被推断为DataRow类。这个程序的运行结果如下所示:

System.Data.DataRowAdded

如果把上述程序中的第 13 行改为:

13: foreach (var row in dt.Rows)

这时,会出错以下编译错误:

Program.cs(16,31): error CS1061:“object”不包含“RowState”的定义,并且找不到可接受类型为“object”的第一个参数的扩展方法“RowState”(是否缺少 using 指令或程序集引用?)

这是因为DataRowCollection类只实现了System.Collections.IEnumerable接口,而没有实现System.Collections.Generic.IEnumerable<DataRow>接口,所以该foreach语句中的 row 变量的类型被推断为System.Object类。

仅实现IEmnumerable接口而没有实现IEnumerable<T>接口的集合类还有非常多,例如:

因为泛型是在 .NET 2.0 中才引入的,上述类中的大部分都是在 .NET 1.0 中已经就有了。但是 Microsoft 应该在 .NET 2.0 以后为上述类实现IEnumerable<T>接口才对。这不能不说是 .NET Framework Base Class Library 的一个遗憾。请参阅 MSDN 论坛上的一个相关的帖子:Missing linq extension method。

幸运的是,在 .NET Framework 3.5 及其以后的版本中,, 在System.Linq命名空间中增加了IEnumerable.Cast<TResult>扩展方法,可以将IEnumerable的元素转换为指定的TResult类型。这样,上述程序第 13 行改为:

13: foreach (var row in dt.Rows.Cast<DataRow>())

就可以正常工作了。当然,在这个场合还有更好的解决方案,就是将第 13 行改为:

13: foreach (DataRow row in dt.Rows)

就可以了。

也有好消息,就是System.Collections.ObjectModel命名空间中的Collection<T>类实现了IEnumerable<T>接口,而Collection<T>类有很多派生类。例如System.Net命名空间中的IPEndPointCollection类就是从Collection<IPEndPoint>类继承,因此也就实现了IEnumerable<IPEndPoint>接口。

版权声明:本文为博主 原创文章,未经博主允许不得转载。

最好的节约是珍惜时间,最大的浪费是虚度年华。

浅谈 System.Data.DataRowCollection 类

相关文章:

你感兴趣的文章:

标签云: