Aja*_*jai 22 c# nullreferenceexception
using System;
using System.Collections.Generic;
class Parent
{
public Child Child { get; set; }
}
class Child
{
public List<string> Strings { get; set; }
}
static class Program
{
static void Main() {
// bad object initialization
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
上面的程序编译很好,但在运行时崩溃,而Object引用没有设置为对象的实例.
如果您在上面的代码段中注意到,我在初始化子属性时省略了new.
显然,正确的初始化方法是:
var parent = new Parent() {
Child = new Child() {
Strings = new List<string> { "hello", "world" }
}
};
Run Code Online (Sandbox Code Playgroud)
我的问题是为什么C#编译器在看到第一个构造时不会抱怨?
为什么破坏的初始化有效语法?
var parent = new Parent() {
Child = {
Strings = { "hello", "world" }
}
};
Run Code Online (Sandbox Code Playgroud)
Jer*_*vel 18
它没有破坏语法,是你在一个简单没有实例化的属性上使用对象初始化器.你写的内容可以扩展到
var parent = new Parent();
parent.Child.Strings = new List<string> { "hello", "world" };
Run Code Online (Sandbox Code Playgroud)
其中投NullReferenceException:你想分配财产Strings由酒店载Child而Child依然null.使用构造函数首先实例化Child,处理此问题.
Guf*_*ffa 11
初始化没有任何问题,但它正在尝试初始化不存在的对象.
如果类具有创建对象的构造函数,则初始化有效:
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>();
}
}
Run Code Online (Sandbox Code Playgroud)
您似乎误解了集合初始化程序的作用。
它只是一种语法糖,它将花括号中的列表转换为对必须在要初始化的集合对象上定义的方法的一系列调用Add()。因此,
您= { "hello", "world" }的与
.Add("hello");
.Add("world");
Run Code Online (Sandbox Code Playgroud)
显然,如果未创建集合,此操作将失败并返回NullReferenceException。
小智 4
第二种语法对于只读属性有效。如果您更改代码以在各自的构造函数中初始化 Child 和 Strings 属性,则该语法有效。
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" }
}
};
}
}
Run Code Online (Sandbox Code Playgroud)