代码之家  ›  专栏  ›  技术社区  ›  Jake

自定义集合初始值设定项

c#
  •  46
  • Jake  · 技术社区  · 15 年前

    实现的类 IEnumerable 并提供一个 public void Add(/* args */) 可以像下面的示例一样初始化函数:

    List<int> numbers = new List<int>{ 1, 2, 3 };
    

    它调用 Add(int) 函数3x初始化后 List<int> .

    有没有一种方法可以为我自己的类显式定义这种行为?例如,是否可以让初始值设定项调用适当的 Add() 超载?

    2 回复  |  直到 9 年前
        1
  •  62
  •   Mehrdad Afshari    15 年前

    不,编译器需要名为 Add 以便集合初始值设定项工作。这在C规范中定义,不能更改:

    C语言规范-7.5.10.3集合初始值设定项

    应用集合初始值设定项的集合对象必须是实现 System.Collections.IEnumerable 或者发生编译时错误。对于每个指定的元素,集合初始值设定项将调用 添加 方法,将元素初始值设定项的表达式列表作为参数列表,为每个调用应用普通重载解决方案。因此, 集合对象必须包含适用的 添加 方法 对于每个元素初始值设定项。 [强调矿井]

    当然, 添加 方法可以接受多个参数(如 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);
    
        2
  •  4
  •   dizarter    9 年前

    添加一个有效的示例答案。Afaik,只有添加才有效。代码段取自 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 }
    };