程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 淺談 System.Data.DataRowCollection類

淺談 System.Data.DataRowCollection類

編輯:C#入門知識

我們來看看以下程序吧:

01:  using System;
02:  using System.Data;
03:  using System.Linq;
04:  
05:  namespace Skyiv.Ben
06:  {
07:    class Program
08:    {
09:      static void Main()
10:      {
11:        var dt = new DataTable();
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.DataRow
Added

 

如果把上述程序中的第 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> 接口的集合類還有非常多,例如:

  • System.Data.DataColumnCollection
  • System.Data.ConstraintCollection
  • System.Data.Common.DataTableMappingCollection
  • System.Windows.Forms.DataGridViewRowCollection
  • System.Web.UI.WebControls.GridViewRowCollection

因為泛型是在 .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> 接口。

參考資料

  1. Missing linq extension method
  2. MSDN: foreach, in (C# Reference)
  3. MSDN: DataRowCollection 類(System.Data)
  4. MSDN: IPEndPointCollection 類(System.Net)
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved