I can initialize a List<int> like new List<int>{1,2,3,4,5};
However List<T>
does not have a constructor which accepts a single parameter.
So I tried to run this through the debugger and it seems to be calling the Add method.
So how does the compiler know which method to invoke to add each individual element.
This may be a silly question but I am a bit confused.
Thanks
The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name and its parameters.
C# - Object Initializer Syntax NET 3.5) introduced Object Initializer Syntax, a new way to initialize an object of a class or collection. Object initializers allow you to assign values to the fields or properties at the time of creating an object without invoking a constructor. Example: Object Initializer Syntax.
There are two ways to specify initializers for arrays: With C89-style initializers, array elements must be initialized in subscript order. Using designated initializers, which allow you to specify the values of the subscript elements to be initialized, array elements can be initialized in any order.
Initialization lists allow you to choose which constructor is called and what arguments that constructor receives. If you have a reference or a const field, or if one of the classes used does not have a default constructor, you must use an initialization list.
This is a collection initializer, a C# 3.0 language feature. It requires:
IEnumerable
(although this is never used for initialization)Add
methodIt simply calls the Add
method for each term.
You can also use tuples if the Add
accepts multiple values, for example dictionaries. Each term is then {key,value}
:
new Dictionary<int,string> {{1,"abc"},{2,"def"}};
For an example of using this for a bespoke type:
class Program
{
static void Main()
{
new Foo { 1, "abc", { 2, "def" } };
}
}
class Foo : IEnumerable
{
public void Add(int a) { }
public void Add(string b) { }
public void Add(int a, string b) { }
// must implement this!! (but never called)
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
}
Every type that has the method Add and implements IEnumerable can be initialized this way. The compiler just compiles your code as if you used this Add method.
take a look here
Look at this method.
public void CreateList()
{
List<int> list = new List<int> { 1, 2, 3, 4, 5 };
}
After compiling this, the MSIL looks like this..
.method public hidebysig instance void CreateList() cil managed
{
// Code size 50 (0x32)
.maxstack 2
.locals init ([0] class [mscorlib]System.Collections.Generic.List`1<int32> list,
[1] class [mscorlib]System.Collections.Generic.List`1<int32> '<>g__initLocal0')
IL_0000: nop
IL_0001: newobj instance void class [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stloc.1
IL_0007: ldloc.1
IL_0008: ldc.i4.1
IL_0009: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_000e: nop
IL_000f: ldloc.1
IL_0010: ldc.i4.2
IL_0011: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_0016: nop
IL_0017: ldloc.1
IL_0018: ldc.i4.3
IL_0019: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_001e: nop
IL_001f: ldloc.1
IL_0020: ldc.i4.4
IL_0021: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_0026: nop
IL_0027: ldloc.1
IL_0028: ldc.i4.5
IL_0029: callvirt instance void class [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
IL_002e: nop
IL_002f: ldloc.1
IL_0030: stloc.0
IL_0031: ret
} // end of method Program::CreateList
As you can observe, It's just a syntactic sugar and the compiler replaces the intialization by consecutive calls of Add().
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