Search code examples
c#listgenericsnew-operator

Why initialize lists with the new keyword rather than simply declare them?


I have a basic grasp on the C# language, knowing how to do things without much understanding of why. I noticed today that I habitually add the new keyword when initializing a list (ex. public List<Foo> foos = new List<Foo>();) without realizing why I am doing the initialization in the first place. This just piqued my curiosity and I had to come here and ask (after searching of course).

I tried simply declaring the list

public List<Foo> foos;

and it worked just fine with my code, so why was I taught to always initialize lists with the new keyword?
What is the difference?
I assume it has to do with allocating memory, but again, I have an elementary understanding of such things.


SOLVED: @JOSEFtw's answer below demonstrated that Unity's compiler will automatically initialize a list that is simply declared with public List<Foo> foos;. This got me mixed up and anywhere outside of Unity will throw a NullReferenceException if you don't initialize a list.


EDIT: @UnholySheep asked for a minimal, reproducible example in the comments. After struggling with formatting there, I decided to add it here:

public class ListManager : MonoBehaviour
{
    public List<int> ints;

    public void AddInt(int i)
    {
        ints.Add(i);
    }

    void Start()
    {
        AddInt(3);
        AddInt(6);
        AddInt(9);

        foreach (int i in ints)
            Debug.Log($"Int {ints.IndexOf(i) + 1} is {i}");
    }
}

For me, this produces the result:

Int 1 is 3
Int 2 is 6
Int 3 is 9

even though a NullReferenceException is to be expected.

This is using Unity's compiler, which could be why public List<int> ints; is working the same as public List<int> ints = new List<int>();. Perhaps it's just the compiler making things proper in the background? For those unfamiliar with Unity, Debug.Log is similar to Console.WriteLine and void Start() is similar to void main().


Solution

  • EDIT: I now see that you are using Unity. Take a look at this answer: https://gamedev.stackexchange.com/a/129346

    Unity's editor automatically creates the new List () part when generating the game

    The below portion of my answer still stands true though if you are not using Unity.

    using System;
    using System.Collections.Generic;
    
    public class Program
    {
        public static List<string> MyList;
        public static void Main()
        {
            MyList.Add("boom");
        }
    }
    

    Will throw the following error if you try to use it without initialize it:

    System.NullReferenceException: Object reference not set to an instance of an object.
    

    I created a fiddle for you that shows what happens if you run the code: https://dotnetfiddle.net/dUlxo6