为什么要用 new 关键字初始化列表而不是简单地声明它们?
Why initialize lists with the new keyword rather than simply declare them?
我对 C# 语言有基本的了解,知道 如何 做事,但不太了解 为什么。我今天注意到我在初始化列表时习惯性地添加 new
关键字(例如 public List<Foo> foos = new List<Foo>();
),而没有意识到我首先要进行初始化的原因。这激起了我的好奇心,我不得不来这里问问(当然是在搜索之后)。
我尝试简单地声明列表
public List<Foo> foos;
它在我的代码中工作得很好,那么为什么我被教导总是用 new
关键字初始化列表?
有什么区别?
我认为它与分配内存有关,但同样,我对这些事情有基本的了解。
已解决: @JOSEFtw 在下面的回答表明 Unity 的编译器将自动初始化一个简单地用 public List<Foo> foos;
声明的列表。这让我感到困惑,如果您不初始化列表,Unity 之外的任何地方都会抛出 NullReferenceException。
编辑: @UnholySheep 在评论中要求提供一个最小的、可重现的示例。在努力格式化之后,我决定在这里添加它:
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}");
}
}
对我来说,这会产生结果:
Int 1 is 3
Int 2 is 6
Int 3 is 9
即使 NullReferenceException 是预期的。
这是使用 Unity 的编译器,这可能就是 public List<int> ints;
与 public List<int> ints = new List<int>();
工作相同的原因。也许这只是编译器在后台使事情变得正确?对于不熟悉 Unity 的人,Debug.Log
类似于 Console.WriteLine
,void Start()
类似于 void main()
。
编辑:我现在看到您正在使用 Unity。
看看这个答案:https://gamedev.stackexchange.com/a/129346
Unity's editor automatically creates the new List () part when generating the game
如果您不使用 Unity,我的回答的以下部分仍然适用。
using System;
using System.Collections.Generic;
public class Program
{
public static List<string> MyList;
public static void Main()
{
MyList.Add("boom");
}
}
如果您尝试在未初始化的情况下使用它,将抛出以下错误:
System.NullReferenceException: Object reference not set to an instance of an object.
我为您创建了一个 fiddle,它显示了如果您 运行 代码会发生什么:https://dotnetfiddle.net/dUlxo6
我对 C# 语言有基本的了解,知道 如何 做事,但不太了解 为什么。我今天注意到我在初始化列表时习惯性地添加 new
关键字(例如 public List<Foo> foos = new List<Foo>();
),而没有意识到我首先要进行初始化的原因。这激起了我的好奇心,我不得不来这里问问(当然是在搜索之后)。
我尝试简单地声明列表
public List<Foo> foos;
它在我的代码中工作得很好,那么为什么我被教导总是用 new
关键字初始化列表?
有什么区别?
我认为它与分配内存有关,但同样,我对这些事情有基本的了解。
已解决: @JOSEFtw 在下面的回答表明 Unity 的编译器将自动初始化一个简单地用 public List<Foo> foos;
声明的列表。这让我感到困惑,如果您不初始化列表,Unity 之外的任何地方都会抛出 NullReferenceException。
编辑: @UnholySheep 在评论中要求提供一个最小的、可重现的示例。在努力格式化之后,我决定在这里添加它:
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}");
}
}
对我来说,这会产生结果:
Int 1 is 3
Int 2 is 6
Int 3 is 9
即使 NullReferenceException 是预期的。
这是使用 Unity 的编译器,这可能就是 public List<int> ints;
与 public List<int> ints = new List<int>();
工作相同的原因。也许这只是编译器在后台使事情变得正确?对于不熟悉 Unity 的人,Debug.Log
类似于 Console.WriteLine
,void Start()
类似于 void main()
。
编辑:我现在看到您正在使用 Unity。 看看这个答案:https://gamedev.stackexchange.com/a/129346
Unity's editor automatically creates the new List () part when generating the game
如果您不使用 Unity,我的回答的以下部分仍然适用。
using System;
using System.Collections.Generic;
public class Program
{
public static List<string> MyList;
public static void Main()
{
MyList.Add("boom");
}
}
如果您尝试在未初始化的情况下使用它,将抛出以下错误:
System.NullReferenceException: Object reference not set to an instance of an object.
我为您创建了一个 fiddle,它显示了如果您 运行 代码会发生什么:https://dotnetfiddle.net/dUlxo6