2011-06-03 129 views
4

是否有任何優勢,使用這種IEnumerable的<string>和string []

private static IEnumerable<string> GetColumnNames(this IDataReader reader) 
     { 
      for (int i = 0; i < reader.FieldCount; i++) 
       yield return reader.GetName(i); 

     } 

,而不是這個

private static string[] GetColumnNames(this IDataReader reader) 
    { 
     var columnNames = new string[reader.FieldCount]; 
     for (int i = 0; i < reader.FieldCount; i++) 
      columnNames[i] = reader.GetName(i); 

     return columnNames; 
    } 

這是我如何使用此方法

int orderId = _noOrdinal; 
    IEnumerable<string> columnNames = reader.GetColumnNames(); 
    if (columnNames.Contains("OrderId")) 
      orderId = reader.GetOrdinal("OrderId"); 
    while (reader.Read()) 
      yield return new BEContractB2CService 
        { 
         //.................. 
         Order = new BEOrder 
          { Id = orderId == _noOrdinal ? 
              Guid.Empty : reader.GetGuid(orderId) 
          }, 
//............................ 
+3

http://stackoverflow.com/questions/764748/whats-the-difference-between-ienumerable-and-array-ilist-and-list – Bolu 2011-06-03 11:48:45

回答

6

的兩種方法是完全不同的,所以這取決於你後來要做的結果,我會說。

例如:

第一種情況需要所述數據讀取器保持打開,直到結果被讀出,第二個沒有。因此,您需要多久才能保持這一結果,並且是否希望讓數據讀取器保持長時間的打開狀態?

如果您一定要讀取數據,那麼第一種情況的執行效率會降低,但如果您經常不讀取數據,那麼性能可能會更高,尤其是在數據量很大的情況下。

您的第一個案例的結果只能讀取/迭代/搜索一次。然後可以多次存儲和搜索第二種情況。

如果你有大量的數據,那麼第一種情況可以用這種方式,你不需要一次把所有的數據帶入內存。但是,這又取決於你在調用方法中使用IEnumerable做什麼。

編輯: 考慮到你的用例,這些方法對於任何給定度量的「良好性」可能都非常相當。表不傾向於有很多列,並且您使用.Contains確保每次都讀取數據。就我個人而言,如果僅僅因爲這是一種更直接的方法,我會堅持使用數組方法。

代碼的下一行是什麼?它是在尋找不同的列名?如果是這樣,第二種情況是唯一的出路。

+0

@James Gaunt,你的回答很好。看看我編輯的代碼的下一行。 – Alexandre 2011-06-03 12:06:21

+0

不正確:IEnumerable.Contains實際上確保只有在OrderID名稱不在列表中或上一個位置時纔會讀取所有數據。 – phoog 2011-06-03 12:09:47

+0

謝謝。所以如果你不打算繼續使用columnNames的結果,我真的不認爲這兩種方法之間有太大的區別,所以我只是使用你更熟悉的方法。 – 2011-06-03 12:14:02

2

第一個是懶惰的。那就是你的代碼在迭代enumerable之前不會被評估,因爲你使用閉包來運行代碼,直到它產生一個值,然後把控制權轉回調用代碼,直到你通過MoveNext迭代到下一個值。另外通過linq你可以通過調用第一個然後調用ToArray來實現第二個。您可能想要這樣做的原因是爲了確保您在調用時獲取數據,而不是在兩者之間的值發生變化時進行迭代。

2

一個優點與內存消耗有關。如果FieldCount是100萬,那麼後者需要分配一個有100萬條記錄的數組,而前者不需要。

這個好處取決於方法如何被消耗。例如,如果您正在一個接一個地處理文件列表,則不需要預先知道所有文件。

3

關於我頭頂的理由:陣列版本意味着您必須先花時間構建陣列。大多數代碼的客戶端可能不一定需要特定的數組。大多數情況下,我發現,大多數代碼只是在迭代它,在這種情況下,爲什麼浪費時間構建一個您從未真正需要的數組(或列表作爲替代)。

相關問題