Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

new [] or new List<T>?

I'm just thinking about the styling and performance. Previously I used to write something like,

var strings = new List<string> { "a", "b", "c" };
var ints = new List<int> { 1, 2, 3};

But now I tend to like this style more,

var strings = new [] { "a", "b", "c" }.ToList();
var ints = new [] { 1, 2, 3}.ToList();

I prefer the second style, but now considering - is it really worth to write it like that or maybe it's not that efficient and requires more operations?

like image 273
Alexander Beletsky Avatar asked Mar 30 '12 12:03

Alexander Beletsky


2 Answers

I disagree with Darin: they're not equivalent in terms of performance. The latter version has to create a new array, and ToList will then copy it into the new list. The collection initializer version is equivalent to:

var tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
var ints = tmp;

Assuming the list starts off with a large enough buffer, that won't require any further allocation - although it will involve a few method calls. If you do this for a very large number of items, then it will require more allocations than the ToList version, because it will copy the items as it goes.

The performance difference is likely to be negligible, but it's non-zero (and not clearly better in either direction - there are fewer calls in the array version, but more allocation).

I would concentrate more on style than performance unless you have a reason to suspect that the difference is significant, in which case you should measure rather than just guessing.

Personally I prefer the first form - I think it makes it clearer that you're using a list right from the start. Another alternative would be to write your own static class:

public static class Lists
{
    public static List<T> Of<T>(T item0)
    {
        return new List<T> { item0 };
    }

    public static List<T> Of<T>(T item0, T item1)
    {
        return new List<T> { item0, item1 };
    }

    public static List<T> Of<T>(T item0, T item1, T item2)
    {
        return new List<T> { item0, item1, item2 };
    }

    ... as many times as you really care about, then ...

    public static List<T> Of<T>(params T[] items)
    {
        return items.ToList();
    }
}

Then you can write:

var ints = Lists.Of(1);
var ints = Lists.Of(1, 2, 3);
var ints = Lists.Of(1, 2, 3, 5, 6, 7, 8); // Use the params version

This still makes it clear that you're using lists, but takes advantage of type inference.

You may well consider it overkill though :)

like image 173
Jon Skeet Avatar answered Nov 14 '22 23:11

Jon Skeet


Setting aside the difference between the two from a performance perspective, the former expresses what you are trying to achieve in a better way.

Consider expressing the code in English:

declare a list of strings with these contents

And

declare an array of strings with these contents and then convert it into a list of strings

To me, the first seems more natural. Although I acknowledge the second may be better for you.

like image 36
James Wiseman Avatar answered Nov 14 '22 21:11

James Wiseman