C# 正在初始化列表属性,但不带“";新名单;导致NullReferenceException

C# 正在初始化列表属性,但不带“";新名单;导致NullReferenceException,c#,nullreferenceexception,C#,Nullreferenceexception,这并不是破坏语法,而是您在未实例化的属性上使用对象初始值设定项。你写的东西可以扩展到 var parent = new Parent() { Child = { Strings = { "hello", "world" } } }; var parent=new parent(); parent.Child.Strings=新列表{“hello”,“world”}; 抛出NullReferenceExcept

这并不是破坏语法,而是您在未实例化的属性上使用对象初始值设定项。你写的东西可以扩展到

      var parent = new Parent() {
         Child = {
            Strings = { "hello", "world" }
         }
      };
var parent=new parent();
parent.Child.Strings=新列表{“hello”,“world”};
抛出
NullReferenceException
:当
Child
仍然为
null时,您试图分配属性
子项所包含的属性
字符串

首先使用构造函数实例化
子对象
可以解决这个问题。

第二种语法对只读属性有效。如果更改代码以初始化相应构造函数中的子属性和字符串属性,则语法会起作用

var parent = new Parent();
parent.Child.Strings = new List<string> { "hello", "world" };
类父类
{
公共家长()
{
Child=新的Child();
}
公共子项{get;私有集;}
}
班童
{
公共儿童()
{
字符串=新列表();
}
公共列表字符串{get;private set;}
}
静态类程序
{
静态void Main()
{
//现在一切正常
var parent=新父级
{
孩子=
{
字符串={“你好”,“世界”}
}
};
}
}

初始化没有问题,但它试图初始化不存在的对象

如果类具有创建对象的构造函数,则初始化将起作用:

class Parent
{
    public Parent()
    {
        Child = new Child();
    }

    public Child Child { get; private set; }
}

class Child
{
    public Child()
    {
        Strings = new List<string>();
    }
    public List<string> Strings { get; private set; }
}

static class Program
{
    static void Main()
    {
        // works fine now
        var parent = new Parent
        {
            Child =
            {
                Strings = { "hello", "world" }
            }
        };

    }
}
类父类{
公共子项{get;set;}
公共家长(){
Child=新的Child();
}
}
班童{
公共列表字符串{get;set;}
公共儿童(){
字符串=新列表();
}
}

在编译时,不能始终检查引用null的情况。虽然编译器有时会警告在赋值之前使用变量。编译器工作正常。这是一个运行时错误。

您似乎误解了集合初始值设定项的作用

将大括号中的列表转换为必须在正在初始化的集合对象上定义的列表,这仅仅是一种语法糖。
因此,您的
={“hello”,“world”}
具有与相同的效果

class Parent {
  public Child Child { get; set; }
  public Parent() {
    Child = new Child();
  }
}

class Child {
  public List<string> Strings { get; set; }
  public Child() {
    Strings = new List<string>();
  }
}

显然,如果未创建集合,此操作将失败,并出现NullReferenceException。

请注意,此语法可能会导致一些意外结果和难以发现的错误:

.Add("hello");
.Add("world");

集合初始值设定项与只读属性无关。这段代码之所以有效,是因为您将
Strings=newlist()私有集
。请重新阅读代码。“Child属性不是一个集合,它是一个只读属性。科林的回答具有欺骗性,因此是错误的,@Ajai。”。它指出只读属性和集合初始值设定项的行为之间存在联系。事实并非如此。集合初始值设定项和只读属性彼此不必做任何事情,它们是完全不相关的概念。请参阅我已链接到。矩形初始值设定项是一个
对象初始值设定项
。OP谈论的初始值设定项是集合初始值设定项。集合初始值设定项由编译器转换为一个系列或对
Add()
方法的调用,而不是转换为其他任何内容。此行为与只读属性或
对象初始值设定项
s无关。下一句话,如果更改代码以初始化相应构造函数中的Child和Strings属性,语法是正确的,如果该语句后面有因为对象初始值设定项不创建对象,所以它们只设置属性或向集合中添加项,而不是“它用于只读属性”
class Parent {
  public Child Child { get; set; }
  public Parent() {
    Child = new Child();
  }
}

class Child {
  public List<string> Strings { get; set; }
  public Child() {
    Strings = new List<string>();
  }
}
.Add("hello");
.Add("world");
class Test
{
    public List<int> Ids { get; set; } = new List<int> { 1, 2 };
}

var test = new Test { Ids = { 1, 3 } };

foreach (var n in test)
{
    Console.WriteLine(n);
}
1
2
1
3