Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing a Generic.List in C#

In C#, I can initialize a list using the following syntax.

List<int> intList= new List<int>() { 1, 2, 3 };

I would like to know how that {} syntax works, and if it has a name. There is a constructor that takes an IEnumerable, you could call that.

List<int> intList= new List<int>(new int[]{ 1, 2, 3 });

That seems more "standard". When I deconstruct the default constructor for the List I only see

this._items = Array.Empty;

I would like to be able to do this.

CustomClass abc = new CustomClass() {1, 2, 3};

And be able to use the 1, 2, 3 list. How does this work?

Update

Jon Skeet answered

It's calling the parameterless constructor, and then calling Add:

> List<int> tmp = new List<int>();
> tmp.Add(1); tmp.Add(2); tmp.Add(3);
> List<int> intList = tmp;

I understand what is does. I want to know how. How does that syntax know to call the Add method?

Update

I know, how cliche to accept a Jon Skeet answer. But, the example with the strings and ints is awesome. Also a very helpful MSDN page is:

  • Object and Collection Initializers (C# Programming Guide)
like image 609
Anthony D Avatar asked Apr 15 '09 14:04

Anthony D


People also ask

What is generic list in C#?

The Generic List<T> Class in C# is a collection class that is present in System. Collections. Generic namespace. This Generic List<T> Collection Class represents a strongly typed list of objects which can be accessed by using the index.


5 Answers

This is called a collection initializer. It's calling the parameterless constructor, and then calling Add:

List<int> tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
List<int> intList = tmp;

The requirements for the type are:

  • It implements IEnumerable
  • It has overloads of Add which are appropriate for the argument types you supply. You can supply multiple arguments in braces, in which case the compiler looks for an Add method with multiple parameters.

For example:

public class DummyCollection : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new InvalidOperationException("Not a real collection!");
    }

    public void Add(string x)
    {
        Console.WriteLine("Called Add(string)");
    }

    public void Add(int x, int y)
    {
        Console.WriteLine("Called Add(int, int)");
    }
}

You can then use:

DummyCollection foo = new DummyCollection
{
    "Hi",
    "There",
    { 1, 2 }
};

(Of course, normally you'd want your collection to implement IEnumerable properly...)

like image 62
Jon Skeet Avatar answered Oct 02 '22 11:10

Jon Skeet


Read Object and Collection Initializers (C# Programming Guide). Basically you could this with every custom type that is a list (implements IEnumerable).

like image 38
Cornel Avatar answered Oct 02 '22 12:10

Cornel


They're called collection initializers (also see here), and the way they work is by looking for an Add() method that can do their bidding. It calls Add() for each of the integers you have in your curly braces.

The search for the Add() method is pure compiler magic. It's hardcoded to find a method of that name.

like image 32
mqp Avatar answered Oct 02 '22 12:10

mqp


The name you're loooking for is "Collection Initializer". It works under the hood by looking for a method named Add on the collection type and calling it for every value that you specify.

More details: Object and Collection Initializers (C# Programming Guide)

like image 34
JaredPar Avatar answered Oct 02 '22 12:10

JaredPar


I believe it's a shortcut to the .Add method. I've never tried to override it, though, so I don't know if it's possible.

like image 31
Matt Grande Avatar answered Oct 02 '22 11:10

Matt Grande