给定
public class SomeClassWithAList
{
public List<int> list { get; set; }
}
[Fact]
public void InitListInsideModel()
{
var cashthing = new SomeClassWithAList { list = { 4 } };
}
我的问题是 InitListInsideModel
似乎是一个有效代码,但实际上这段代码不会执行。
System.NullReferenceException : Object reference not set to an instance of an object.
这是怎么回事?我不理解什么基本概念?这是编译器错误吗?为什么 IntelliSense 不警告我不能以这种方式实例化列表?
最佳答案
TLDR
如您所知,修复方法是以一种或另一种方式初始化集合
public List<int> list { get; set; } = new List<T>();
// or
var cashthing = new SomeClassWithAList
{
list = new List<int>(){ 4 }
};
至于为什么你可以这样做而不得到警告?嗯……这是一个有趣的问题。
乍一看,它看起来像一个 roslyn 错误,它允许在对象初始化程序中的集合上使用无效的数组初始化程序语法。
然而,这实际上是设计使然。语法的作用是使用集合 Add
方法的 resolution 添加一个 sequence。为此,需要对集合进行初始化!
你每天都能学到新东西
以下内容
var cashthing = new SomeClassWithAList
{
list = { 4 }
};
new SomeClassWithAList().list.Add(4);
IMO,静态分析 应该能够对此发出警告(尤其是对于可空类型),它也应该在 Object and Collection Initializers (C# Programming Guide) 中得到很好的记录。 .
我唯一能找到合适文档的地方是 C# 语言规范
强调我的
7.6.10.2 Object initializers
...
A member initializer that specifies a collection initializer after the equals sign is an initialization of an embedded collection. Instead of assigning a new collection to the field or property, the elements given in the initializer are added to the collection referenced by the field or property. The field or property must be of a collection type that satisfies the requirements specified in §7.6.10.3.
因此,此功能的正确用法是确保您的集合自动初始化
public List<int> list { get; set; } = new List<T>();
其他资源
在进一步挖掘之后,我发现了以下内容
关于这个确切情况的 GitHub 问题
GitHub 问题,希望向文档添加更多特异性以阐明语言功能
关于c# - 在对象初始值设定项中的嵌入式集合上使用集合初始值设定项时没有警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64949953/