6

コレクション初期化子を使用してリストを初期化できることはわかっています。

var list = new List<string>
{
    "test string 1",
    "test string 2"
};

思い出すと、これは各項目に対して内部的に Add を呼び出します。

List<T>を取るコンストラクタがないのはなぜparams T[] itemsですか?

var list = new List<string>("test string 1", "test string 2");
4

3 に答える 3

17

本当の理由は、設計者が、このわずかな構文糖衣の利点が実装の労力に見合うだけの価値がある、または混乱を引き起こす可能性があると単純に感じなかったことです。

を作成する場合は、わずかな問題がありますList<int>。これはどういう意味ですか?

var list = new List<int>(10);

それは容量が 10 の新しいリストですか、それとも 10 という単一の要素を含む新しいリストですか?

ネタバレ、コンパイラがそれをどのように解釈するかわからない場合:

容量扱いとなります。T以外の場合はint、1 つの要素として扱われます。また、パラメータ名を指定すると、単一のアイテムとして扱われます—List<int>(items:10)

いずれにせよ、次のように書けない理由はありません。

var list = new List<string>(new[] { "test string 1", "test string 2" });

これは、引数を提供するコンストラクターがあった場合にコンパイラーが行うこととまったく同じでありparams、コレクション初期化子よりもわずかに効率的です。これを達成するためにいくつかの余分な文字を入力しなければならないことは、実際には大したことではありません。

于 2013-11-08T23:19:04.183 に答える
8

...作成する説得力のあるケースがないためですか? 特に、単に a を渡すのではなく、それがas としてparams使用されたことを知る方法がないため、その配列をバッキング配列として信頼することはできません。そのため、ベクターの追加の不必要な割り当てになります。 . そして、コレクション初期化子の構文は非常にうまく機能します。正しいサイズで割り当てたい場合は、いつでも次を使用できます。paramsstring[]

var list = new List<string>(2)
{
    "test string 1",
    "test string 2"
};

率直に言って、これが重要になる回数は本当に少ないです。

実際、私は使用量を削除する paramsのに多くの時間を費やしています。忙しいサイトでは、かなりの苦痛を伴います (ホット コード パスで使用した場合)。

于 2013-11-08T23:18:31.270 に答える
3

誰も実装していないからです。

さらに、コレクション初期化子の構文がほぼ同等であるため、これは不要です (@pswg の回答を参照)。

しかし!待ってください...私はとても寛大な気持ちなので、これを私からあなたへの贈り物と考えてください:

public class SpecialListJustForYou<T> : List<T>
{
    public SpecialListJustForYou(int capacity):base(capacity){}
    public SpecialListJustForYou(IEnumerable<T> collection):base(collection){}
    public SpecialListJustForYou():base(){}

    // and here's the magic!
    public SpecialListJustForYou(params T[] items) : base(items == null ? Enumerable.Empty<T>() : items.AsEnumerable()){}
}
于 2013-11-08T23:17:39.140 に答える