8

我在考虑数组和列表,想知道类是否以及如何使实现像它们一样可初始化。让我们以这个类为基础:

class TestClass
{
    private List<int> Numbers = new List<int> ();

    // Insert code here
}

我想做的是获取给定的值并在内部填写我的列表。

TestClass test = new TestClass () { 2, 4, 7, 10 };

通常可能是这样的:

List<int> test = new List<int> () { 2, 4, 7, 10 };

但我想将它用于我自己的自定义类。下一个问题是可选的,是否可以对这种语法做同样的事情:

TestClass test = { 2, 4, 7, 10 };

我认为这不太可能。请注意,这些与此不同:

Cat cat = new Cat() { Name = "Sylvester", Age=8 };

这些是内部字段和属性的直接和可选声明。

另请参阅 MSDN 了解更多信息

4

4 回答 4

9

如此处所述,集合初始化器将适用于任何实现IEnumerable 具有Add()方法的类。

class TestClass : IEnumerable<int>
{
    private List<int> Numbers = new List<int> ();

    public void Add(int n)
    {
        Numbers.Add(n);
    }

    // implement IEnumerable methods down here ...

    public IEnumerator<int> GetEnumerator() => Numbers.GetEnumerator();

    // etc ...
}

请注意,如果您的方法签名中有多个参数Add(),则可以将它们括在花括号中以使用集合初始化器语法。

class TestClass2 : IEnumerable<(int, int)>
{
    private List<int> Numbers = new List<(int, int)> ();

    public void Add(int x, int y)
    {
        Numbers.Add((x, y));
    }

    // implement IEnumerable methods down here ...

    public IEnumerator<(int, int)> GetEnumerator() => Numbers.GetEnumerator();

    // etc ...
}

会这样使用:

var test = new TestClass2 { {2, 3}, {4, 5} };
于 2018-09-13T12:56:35.880 回答
8

您只需要一个Add方法来完成这项工作并实现IEnumerable接口:

class TestClass : IEnumerable<int>
{
    private List<int> Numbers = new List<int> ();

    public void Add(int n)
    {
        Numbers.Add(n);
    }

    public IEnumerator<int> GetEnumerator()
    {
        return Numbers.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }
}

编译器将识别集合初始值设定项语法并尝试找到匹配的Add方法。

于 2018-09-13T12:54:36.583 回答
4

从技术上讲,最低要求是

  1. IEnumerable界面(当然IEnumerable<T>是更好的选择)
  2. Add方法

最小示例(仅演示):

  class TestClass: System.Collections.IEnumerable {
    public void Add(int value) { }

    public IEnumerator GetEnumerator() {
      // Just to demonstrate, do not do this in production code
      return null;
    }
  }

  ...

  TestClass myTest = new TestClass() {1, 2, 3};  

在你的情况下:

  class TestClass: IEnumerable<int> {
    private List<int> Numbers = new List<int>();

    // This is required
    public void Add(int value) {
      Numbers.Add(value);
    }

    public IEnumerator<int> GetEnumerator() {
      return Numbers.GetEnumerator();
    }

    // This is required
    IEnumerator IEnumerable.GetEnumerator() {
      return GetEnumerator();
    }
  }
于 2018-09-13T12:56:56.103 回答
1

回答你的第二个子问题:如果有可能

TestClass test = { 2, 4, 5, 7 };

我认为这在任何地方都不是正确的语法。但是,您可以使用隐式运算符创建看起来像它的东西。

由于您可以像这样实例化一个int arraynew[] {1,2,3,4},您可以在您的TestClass.

public class TestClass {
   private IEnumerable<int> list;
   public TestClass(IEnumerable<int> _list) {
       this.list = _list;
   }

   public static implicit operator(int[] input) {
        return new TestClass(input.ToList());      
   }
}

然后像这样创建一个新的TestClass; TestClass testClass = new[] {1,2,3};

于 2018-09-13T13:08:19.993 回答