I was thinking about arrays and lists and wondering if and how classes can get an implementation to be initializable like them. Let's take this class as basis:
class TestClass
{
private List<int> Numbers = new List<int> ();
// Insert code here
}
What I would like to be able to do is to take the given values and internally fill my list.
TestClass test = new TestClass () { 2, 4, 7, 10 };
What would be normally possible is this:
List<int> test = new List<int> () { 2, 4, 7, 10 };
But I would like to have it for my own custom classes. The next question, which is optional, is if the same can be done for this syntax:
TestClass test = { 2, 4, 7, 10 };
I assume that is less likely to be possible. Note, these are different from this:
Cat cat = new Cat() { Name = "Sylvester", Age=8 };
These are direct and optional declarations of internal fields and properties.
See also MSDN for more info.
List initialization is performed in the following situations: direct-list-initialization (both explicit and non-explicit constructors are considered) 1) initialization of a named variable with a braced-init-list (that is, a possibly empty brace-enclosed list of expressions or nested braced-init-lists)
Below are some of the different ways in which all elements of an array can be initialized to the same value: Initializer List: To initialize an array in C with the same value, the naive way is to provide an initializer list. We use this with small arrays. This will initialize the num array with value 1 at all index.
For Modern C++ there is also a third difference: the way brace initialization is handled. For a structure, brace initialization performs a direct initialization of its members For class types, brace initialization results in a call to a constructor. There’s nothing to stop you adding a constructor to a struct.
If you do, the braced initialization list becomes a call to a constructor. struct POD { int i; int j; POD (int x, int y); }; int main () { POD pod1 { 1, 2 }; // POD::POD (1, 2); }
As stated here, collection initialisers will work on any class that implements IEnumerable
and has an Add()
method.
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 ...
}
Note that if you have more than one parameter in your Add()
method signature, then you can enclose them in curly braces to use collection initialiser syntax.
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 ...
}
Would be used like this:
var test = new TestClass2 { {2, 3}, {4, 5} };
You just need an Add
method to make this work and implement the IEnumerable
interface:
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();
}
}
The compiler will recognize the collection initializer syntax and will try to find a matching Add
method.
Technically, the minimum requirements are
IEnumerable
interface (of course, IEnumerable<T>
is a better choice)Add
methodMinimum example (demonstration only):
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};
In your case:
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With