16

リスト初期化子とオブジェクト初期化子を同時に組み合わせることは可能ですか? 次のクラス定義があるとします。

class MyList : List<int>
{
    public string Text { get; set; }
}

// we can do this
var obj1 = new MyList() { Text="Hello" };

// we can also do that
var obj2 = new MyList() { 1, 2, 3 };

// but this one doesn't compile
//var obj3 = new MyList() { Text="Hello", 1, 2, 3 };

これは仕様によるものですか、それとも c# コンパイラの単なるバグまたは欠落している機能ですか?

4

3 に答える 3

28

いいえ、C# 仕様のセクション 7.6.10 の定義を見ると、object-or-collection-initializer式はanまたはa のいずれかです。object-initializer collection-initializer

anobject-initializerは複数member-initializerの で構成され、それぞれが の形式でinitializer = initializer-valueあるのに対し、 acollection-initializerは複数element-initializerの で構成され、それぞれが anon-assigment-expressionです。

したがって、これは設計によるものであるように見えます - おそらく単純化のためです。正直なところ、これをやりたいと思ったことはありません。(私は通常、最初から派生することはありませんList<int>-代わりに作成します。)私は本当に見たくない:

var obj3 = new MyList { 1, 2, Text = "Hello", 3, 4 };

編集:本当にこれを有効にしたい場合は、これをクラスに入れることができます:

class MyList : List<int>
{
    public string Text { get; set; }
    public MyList Values { get { return this; } }
}

その時点で次のように書くことができます:

var obj3 = new MyList { Text = "Hello", Values = { 1, 2, 3, 4 } };
于 2011-06-06T15:20:10.717 に答える
3

いいえ、バグではありません。これは、言語の設計によるものです。

あなたが書くとき

var obj1 = new MyList() { Text="Hello" };

これは、コンパイラによって効果的に変換されます。

MyList temp = new MyList();
temp.Text = "Hello";
MyList obj = temp;

あなたが書くとき

var obj2 = new MyList() { 1, 2, 3 };

これは、コンパイラによって効果的に変換されます。

MyList temp = new MyList();
temp.Add(1);
temp.Add(2);
temp.Add(3);
MyList obj2 = temp;

最初のケースではオブジェクト初期化子を使用していますが、2 番目のケースではコレクション初期化子を使用していることに注意してください。オブジェクトとコレクションの初期化子のようなものはありません。オブジェクトのプロパティを初期化しているか、コレクションを初期化しています。両方を行うことはできません。これは仕様によるものです。

また、から派生させるべきではありませんList<T>。参照: List<T> を継承してコレクションを実装するのは悪い考えですか?

于 2011-06-06T15:20:34.590 に答える
2

このような機能を取得したい場合は、コンストラクター引数を作成することを検討してください。

var x = new CustomList("Hello World") { 1, 2, 3 }
于 2011-06-06T15:30:19.173 に答える