C#で私は書くことができます
var y = new List<string>(2) { "x" , "y" };
List
「x」と「y」が初期化されたaを取得します。
この初期化構文を受け入れるようにクラスを宣言するにはどうすればよいですか?
つまり、私は書きたいです:
var y = new MyClass(2, 3) { "x" , "y" };
C#で私は書くことができます
var y = new List<string>(2) { "x" , "y" };
List
「x」と「y」が初期化されたaを取得します。
この初期化構文を受け入れるようにクラスを宣言するにはどうすればよいですか?
つまり、私は書きたいです:
var y = new MyClass(2, 3) { "x" , "y" };
C#仕様のセクション7.6.10.3を見てください。
コレクション初期化子が適用されるコレクションオブジェクトは、System.Collections.IEnumerableを実装するタイプである必要があります。そうでない場合、コンパイル時エラーが発生します。指定された要素ごとに、コレクション初期化子は、要素初期化子の式リストを引数リストとしてターゲットオブジェクトに対してAddメソッドを呼び出し、呼び出しごとに通常の過負荷解決を適用します。したがって、コレクションオブジェクトには、各要素の初期化子に適用可能なAddメソッドが含まれている必要があります。
これの非常に簡単な例:
class AddIt : IEnumerable
{
public void Add(String foo) { Console.WriteLine(foo); }
public IEnumerator GetEnumerator()
{
return null; // in reality something else
}
}
class Program
{
static void Main(string[] args)
{
var a = new AddIt() { "hello", "world" };
Console.Read();
}
}
これにより、「hello」が出力され、続いて「world」がコンソールに出力されます。
(2,3)が何を示しているのかわかりません。最初の行のコレクションサイズだと理解しています。Listまたは模倣する必要のある構造から単純に継承できます。
このサンプルをLinqPadでテストしました。
void Main()
{
var list = new Foo{
"a",
"b"
};
list.Dump();
}
class Foo : List<string>{ }
次の構文を使用して、クラスのフィールドを初期化します。
// ...
Car myCar1 = new Car () { Model = "Honda", YearBuilt=2009 };
Car myCar2 = new Car () { Model = "Toyota", YearBuilt=2011 };
// ...
public class Car {
public string Model;
public int YearBuilt;
}
マーカスが指摘しているように、クラスはIEnumerable
インターフェースを実装Add()
し、呼び出し元がアクセスできるメソッドを持っている必要があります。
つまり、このスケルトンの例は機能します。
public class MyClass : IEnumerable
{
public void Add(string item)
{
}
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}