2

変換したい

var aList = new List<string>(new string[] { "elem1", "elem2", "elem3" });

への初期化

var aList = new List<string>() { "elem1", "elem2", "elem3" };

私たちのソースコードで。後者は不要な配列作成や配列→リスト変換が無いと思います。それとも前者も?それとも、コンパイラはとにかくそれを最適化しますか? 後で望ましくない副作用 (または副作用の欠如) に直面することはありますか?

プロジェクトは .NET 4 を使用します。

4

3 に答える 3

4

それらは完全に同等ではありません。

  1. 最初のケースでは、新しい配列を作成し、それをコンストラクターに渡します。List<T>コンストラクターは、同じサイズの独自の内部配列を作成し、ソース配列のメソッドを呼び出して、ソース配列CopyToからアイテムを内部配列にコピーします。

  2. List<T>2 番目のケースでは、最初は空の配列 ( size ) を使用して new を作成し_defaultCapacity = 4、次に List のAddメソッドを呼び出します。これにより、要素を追加するときに内部配列のサイズが数回変更される可能性があります。

CopyToしたがって、最初のケースでは、 List の内部配列のサイズを変更する必要がないこと、およびiterative ではなく潜在的に効率的なメソッドを呼び出すことでメリットが得られAddますが、メモリ内に一度に 2 つの配列を作成する必要があります。

2 つの配列の作成を回避し、リストの内部配列のサイズを変更しないようにするためにできることの 1 つを次に示します。

var aList = new List<string>(3) { "elem1", "elem2", "elem3" };

マジック定数 があるため、プロダクション コードには必ずしもこれをお勧めしません3が、とにかく、他の 3 つのマジック定数が既に存在します。

于 2013-06-24T21:00:09.780 に答える
1

後者は次のようにコンパイルされます。

aList = new List<string();
aList.Add("elem1");
aList.Add("elem2");
aList.Add("elem3");

コンストラクターは、次のようなことを行っているように見えます (いくつかのエラー処理があります)。

foreach(var t in items)
    Add(t);

つまり、配列の作成は不要です。マイクロ最適化については、あなたが提案しているように最適化する方がおそらく良いでしょう。ただし、実際には、結果に大きな違いはありません。

于 2013-06-24T20:50:50.457 に答える
1

変換されたコードが次のようになる場合:

var aList = new List<string>(3 /* !capacity specified */) { "elem1", "elem2", "elem3" };

「不要な配列作成」はありません(List<>::_defaultCapacity以上の項目を指定した場合)。

_defaultCapacity == 4 であるため、3 つ (または 4 つ) の文字列をコーディングすると、「不要な配列の作成」も発生しません。

つまり、2 番目のコード (容量を指定せずにコレクション初期化子を使用) では、内部の List<> の配列を数回再作成できます。

于 2013-06-24T21:04:01.940 に答える