开发者

IEnumerable<string> and string[]

开发者 https://www.devze.com 2023-03-10 09:02 出处:网络
Is there any advantage to using this private static IEnumerable<string> GetColumnNames(this IDataReader reader)

Is there any advantage to using this

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

        }

instead of this

  private static string[] GetColumnNames(this IDat开发者_运维百科aReader reader)
    {
        var columnNames = new string[reader.FieldCount];
        for (int i = 0; i < reader.FieldCount; i++)
             columnNames[i] = reader.GetName(i);

        return columnNames;
    }

Here is how I use this method

    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)
                          },
 //............................


The two approaches are quite different so it depends on what you are subsequently going to do with the result I would say.

For example:

The first case requires the data reader to remain open until the result is read, the second doesn't. So how long are you going to hold this result for and do you want to leave the data reader open that long.

The first case is less performant if you are definitely going to read the data, but probably more performant if you often don't, particularly if there is a lot of data.

The result from your first case should only be read/iterated/searched once. Then second case can be stored and searched multiple times.

If you have a large amount of data then the first case could be used in such a way that you don't need to bring all that data in to memory in one go. But again that really depends on what you do with the IEnumerable in the calling method.

Edit: Given your use-case the methods are probably pretty much equivalent for any given measure of 'good-ness'. Tables don't tend to have many columns, and your use of .Contains ensures the data will be read every time. Personally I would stick with the array method here if only because it's a more straightforward approach.

What's the next line of the code... is it looking for a different column name? If so the second case is the only way to go.


On reason off the top of my head: The array version means you have to spend time building the array first. Most of the code's clients may not necessarily need a specific array. Mostly, i've found, that most code is just going to iterate over it in which case, why waste time building an array (or list as an alternative) you never actually need.


The first one is lazy. That is your code is not evaluated until you iterate the enumerable and because you use closures it will run the code until it yields a value then turn control back to the calling code until you iterate to the next value via MoveNext. Additionally with linq you can achieve the second one by calling the first and then calling ToArray. The reason you might want to do this is to make sure you get the data as it is when you make the call versus when you iterate in case the values change in between.


One advantage has to do with memory consumption. If FieldCount is say 1 million, then the latter needs to allocate an array with 1 million entries, while the former does not.

This benefit depends on how the method is consumed though. For example, if you are processing a list of files one-by-one, then there is no need to know all the files up front.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号