为什么我不能将自动实现的 getter 和 setter 与列表一起使用? (统一,C#)
Why can't I use automatically implemented getters and setters with a List? (Unity, C#)
我正在尝试更好地了解 getter 和 setter。
我知道我可以使用自动实现的 getter 和 setter,例如 public Vector3 Position { get; set; }
as shorthand for
private Vector3 _position;
public Vector3 Position
{
get {return _position;}
set{_position = value;}
}
但我不明白为什么这对列表不起作用。如果我尝试声明一个列表,如:
List<Vector3> Positions { get; set;}
Unity 向我抛出空引用异常。
但是如果我使用长格式:
private List<Vector3> _position = new List<Vector3>();
public List<Vector3> Position
{
get {return _position;}
set{_position = value;}
}
它工作得很好。我认为这与声明列表的方式有关,但我想知道这里到底发生了什么。
当你写这篇文章时
List<Vector3> Positions { get; set;}
你声明了一个 List<Vector3>
类型的 属性,但是你没有给它分配任何东西,所以试图取消引用它,例如
Positions.Add(vec3);
将抛出 NullReferenceException
。您可以继续使用自动属性并初始化您的列表,如:
List<Vector3> Positions { get; set;} = new List<Vector3>();
C# 有值类型和引用类型的概念。值类型“像整数一样”——值类型的变量实际上存储值,并且它有一个默认值(通常是某种零)。
另一方面,引用类型是对内存中某物的引用,引用类型的变量不存储实际对象,而是存储实际对象的地址。如果你还没有初始化它,引用类型变量默认为零,a.k.a。空。
Vector3 是值类型。列表是引用类型。这解释了不同的行为,以及为什么您的第二个 List 示例有效 - 在这种情况下,您已经明确创建并初始化了列表对象并将您的引用指向它。
这也是为什么一般来说,在列表 属性 上使用 set
方法不是一个好主意。你不想让外部调用者完全改变它指向的列表,你想改变你已经拥有的实际列表的内容。
我正在尝试更好地了解 getter 和 setter。
我知道我可以使用自动实现的 getter 和 setter,例如 public Vector3 Position { get; set; }
as shorthand for
private Vector3 _position;
public Vector3 Position
{
get {return _position;}
set{_position = value;}
}
但我不明白为什么这对列表不起作用。如果我尝试声明一个列表,如:
List<Vector3> Positions { get; set;}
Unity 向我抛出空引用异常。
但是如果我使用长格式:
private List<Vector3> _position = new List<Vector3>();
public List<Vector3> Position
{
get {return _position;}
set{_position = value;}
}
它工作得很好。我认为这与声明列表的方式有关,但我想知道这里到底发生了什么。
当你写这篇文章时
List<Vector3> Positions { get; set;}
你声明了一个 List<Vector3>
类型的 属性,但是你没有给它分配任何东西,所以试图取消引用它,例如
Positions.Add(vec3);
将抛出 NullReferenceException
。您可以继续使用自动属性并初始化您的列表,如:
List<Vector3> Positions { get; set;} = new List<Vector3>();
C# 有值类型和引用类型的概念。值类型“像整数一样”——值类型的变量实际上存储值,并且它有一个默认值(通常是某种零)。
另一方面,引用类型是对内存中某物的引用,引用类型的变量不存储实际对象,而是存储实际对象的地址。如果你还没有初始化它,引用类型变量默认为零,a.k.a。空。
Vector3 是值类型。列表是引用类型。这解释了不同的行为,以及为什么您的第二个 List 示例有效 - 在这种情况下,您已经明确创建并初始化了列表对象并将您的引用指向它。
这也是为什么一般来说,在列表 属性 上使用 set
方法不是一个好主意。你不想让外部调用者完全改变它指向的列表,你想改变你已经拥有的实际列表的内容。