145

.NETは、パフォーマンスがほぼ同じである汎用リストコンテナを提供します(配列とリストのパフォーマンスの質問を参照)。ただし、初期化はまったく異なります。

配列はデフォルト値で非常に簡単に初期化でき、定義上、すでに特定のサイズがあります。

string[] Ar = new string[10];

これにより、ランダムなアイテムを安全に割り当てることができます。

Ar[5]="hello";

リストを使用すると、物事はよりトリッキーになります。同じ初期化を行う2つの方法がわかりますが、どちらもエレガントとは言えません。

List<string> L = new List<string>(10);
for (int i=0;i<10;i++) L.Add(null);

また

string[] Ar = new string[10];
List<string> L = new List<string>(Ar);

よりクリーンな方法は何でしょうか?

編集:これまでの回答は容量に関するものであり、これはリストの事前入力以外のものです。たとえば、容量が10で作成されたばかりのリストでは、実行できません。L[2]="somevalue"

編集2:人々は、リストが意図された方法ではないので、なぜ私がこのようにリストを使用したいのか疑問に思います。私は2つの理由を見ることができます:

  1. リストは「次世代」の配列であり、ほとんどペナルティなしで柔軟性を追加していると非常に説得力のある主張をすることができます。したがって、デフォルトでそれらを使用する必要があります。初期化するのは簡単ではないかもしれないと指摘しています。

  2. 私が現在書いているのは、より大きなフレームワークの一部としてデフォルトの機能を提供する基本クラスです。私が提供するデフォルトの機能では、リストのサイズは高度にわかっているため、配列を使用することもできます。ただし、基本クラスに動的に拡張する機会を提供したいので、リストを選択します。

4

16 に答える 16

167
List<string> L = new List<string> ( new string[10] );
于 2009-03-10T20:04:08.967 に答える
96

これが頻繁に必要になるとは言えませんが、なぜこれが必要なのかについて詳しく教えてください。私はおそらくそれをヘルパークラスの静的メソッドとして配置します:

public static class Lists
{
    public static List<T> RepeatedDefault<T>(int count)
    {
        return Repeated(default(T), count);
    }

    public static List<T> Repeated<T>(T value, int count)
    {
        List<T> ret = new List<T>(count);
        ret.AddRange(Enumerable.Repeat(value, count));
        return ret;
    }
}

使用することもできますEnumerable.Repeat(default(T), count).ToList()が、バッファーのサイズ変更のために非効率的です。

が参照型の場合、パラメータに渡された参照のコピーTが格納されるため、すべて同じオブジェクトを参照することに注意してください。ユースケースに応じて、それが希望する場合とそうでない場合があります。countvalue

編集:コメントに記載されているように、必要にRepeated応じてループを使用してリストにデータを入力できます。それも少し速くなります。個人的には、Repeatより説明的なコードを使用しているので、現実の世界ではパフォーマンスの違いは関係ないと思いますが、マイレージは異なる場合があります。

于 2009-01-21T21:00:19.217 に答える
23

引数としてint( "capacity")を取るコンストラクターを使用します。

List<string> = new List<string>(10);

編集:私はフレデリクに同意することを追加する必要があります。そもそもリストを使用することの背後にある理由全体に反する方法でリストを使用しています。

EDIT2:

編集2:私が現在書いているのは、より大きなフレームワークの一部としてデフォルトの機能を提供する基本クラスです。私が提供するデフォルトの機能では、リストのサイズは高度にわかっているため、配列を使用することもできます。ただし、基本クラスに動的に拡張する機会を提供したいので、リストを選択します。

なぜ誰かがすべてnull値のリストのサイズを知る必要があるのでしょうか?リストに実際の値がない場合、長さは0になると思います。とにかく、これが不器用であるという事実は、クラスの意図された使用に反していることを示しています。

于 2009-01-21T20:56:16.697 に答える
11

最初に必要な項目の数で配列を作成し、次に配列をリストに変換します。

int[] fakeArray = new int[10];

List<int> list = fakeArray.ToList();
于 2016-09-02T10:54:18.410 に答える
8

固定値の N 個の要素でリストを初期化する場合:

public List<T> InitList<T>(int count, T initValue)
{
  return Enumerable.Repeat(initValue, count).ToList();
}
于 2009-01-21T21:24:23.550 に答える
7

固定値でリストを初期化したいのに、なぜリストを使用しているのですか?パフォーマンスのために、初期容量を指定したいのは理解できますが、必要に応じて拡張できる通常の配列に対するリストの利点の1つではありませんか?

これを行うとき:

List<int> = new List<int>(100);

容量が100整数のリストを作成します。これは、101番目のアイテムを追加するまで、リストを「拡大」する必要がないことを意味します。リストの基になる配列は、100の長さで初期化されます。

于 2009-01-21T20:57:37.677 に答える
5

データとの位置的な関連付けの必要性を強調しているように見えるので、連想配列の方が適切ではないでしょうか?

Dictionary<int, string> foo = new Dictionary<int, string>();
foo[2] = "string";
于 2009-01-23T13:30:50.633 に答える
4

そのようなリストの内容を初期化することは、実際にはリストの目的ではありません。リストはオブジェクトを保持するように設計されています。特定の番号を特定のオブジェクトにマップする場合は、リストの代わりに、ハッシュテーブルやディクショナリなどのキーと値のペア構造を使用することを検討してください。

于 2009-01-21T20:59:30.310 に答える
1
string [] temp = new string[] {"1","2","3"};
List<string> temp2 = temp.ToList();
于 2009-01-21T21:05:17.613 に答える
1

Linq を使用して、リストをデフォルト値で巧みに初期化できます。( David Bの答えに似ています。)

var defaultStrings = (new int[10]).Select(x => "my value").ToList();

さらに一歩進んで、各文字列を個別の値「string 1」、「string 2」、「string 3」などで初期化します。

int x = 1;
var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
于 2014-11-24T19:15:40.033 に答える
0

IList に関する通知: MSDN IList 備考: 「IList の実装は、読み取り専用、固定サイズ、および可変サイズの 3 つのカテゴリに分類されます。(...) このインターフェイスの汎用バージョンについては、を参照してください System.Collections.Generic.IList<T>。」

IList<T>は から継承せずIList(ただし、 と の両方をList<T>実装します)、常に可変サイズです。.NET 4.5以降、私たちも持っていますが、AFAIKでは、探している固定サイズの汎用リストはありません。IList<T>IListIReadOnlyList<T>

于 2016-11-09T09:27:18.500 に答える