可以初始化实现IEnumerable
并提供public void Add(/* args */)
函数的类,如下例所示:
List<int> numbers = new List<int>{ 1, 2, 3 };
在初始化Add(int)
后调用List<int>
函数。
有没有办法为我自己的类显式定义这种行为?例如,我可以让初始化程序调用除适当的Add()
重载之外的函数吗?
答案 0 :(得分:63)
不,编译器需要一个名为Add
的方法才能使集合初始化程序起作用。这是在C#规范中定义的,不能更改:
C#语言规范 - 7.5.10.3集合初始化程序
应用集合初始值设定项的集合对象必须是实现
System.Collections.IEnumerable
的类型,否则会发生编译时错误。对于按顺序的每个指定元素,集合初始值设定项在目标对象上调用Add
方法,并将元素初始值设定项的表达式列表作为参数列表,为每个调用应用正常的重载决策。因此, 集合对象必须包含适用于每个元素初始值设定项的Add
方法 。 [强调我的]
当然,Add
方法可以使用多个参数(例如Dictionary<TKey, TValue>
):
dic = new Dictionary<int, int> {
{ 1, 2 },
{ 3, 4 }
};
// translated to:
dic = new Dictionary<int, int>();
dic.Add(1, 2);
dic.Add(3, 4);
答案 1 :(得分:4)
添加一个有效的示例答案。 AFAIK,只有Add才有效。摘自Marius Schulz
的代码段// simple struct which represents a point in three-dimensional space
public struct Point3D
{
public readonly double X;
public readonly double Y;
public readonly double Z;
public Point3D(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
}
// implementation of a collection of points, which respects
// the compiler convention for collection initializers and
// therefore both implements IEnumerable<T> and provides
// a public Add method
public class Points : IEnumerable<Point3D>
{
private readonly List<Point3D> _points;
public Points()
{
_points = new List<Point3D>();
}
public void Add(double x, double y, double z)
{
_points.Add(new Point3D(x, y, z));
}
public IEnumerator<Point3D> GetEnumerator()
{
return _points.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
// instantiate the Points class and fill it with values like this:
var cube = new Points
{
{ -1, -1, -1 },
{ -1, -1, 1 },
{ -1, 1, -1 },
{ -1, 1, 1 },
{ 1, -1, -1 },
{ 1, -1, 1 },
{ 1, 1, -1 },
{ 1, 1, 1 }
};