2011-06-03 76 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

关于我头顶的理由:阵列版本意味着您必须先花时间构建阵列。大多数代码的客户端可能不一定需要特定的数组。大多数情况下,我发现,大多数代码只是在迭代它,在这种情况下,为什么浪费时间构建一个您从未真正需要的数组(或列表作为替代)。

相关问题