为啥我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#)

Posted

技术标签:

【中文标题】为啥我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#)【英文标题】:Why can't I use automatically implemented getters and setters with a List? (Unity, C#)为什么我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#) 【发布时间】:2022-01-10 07:14:32 【问题描述】:

我正在尝试更好地了解 getter 和 setter。

我知道我可以使用自动实现的 getter 和 setter,例如 public Vector3 Position get; set; 作为简写

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; 

它工作得很好。我认为这与声明列表的方式有关,但我想知道这里到底发生了什么。

【问题讨论】:

因为在第二个示例中,您使用此代码“new List()”显式实例化列表。在您的第一个示例中,该列表从未实例化,因此为空。 【参考方案1】:

当你写这篇文章时

List<Vector3> Positions  get; set;

你声明了一个List&lt;Vector3&gt;类型的属性,但你没有给它分配任何东西,所以尝试取消引用它,例如

Positions.Add(vec3);

将抛出一个NullReferenceException。您可以继续使用自动属性并初始化您的列表,例如:

List<Vector3> Positions  get; set; = new List<Vector3>();

【讨论】:

太棒了。很有帮助,谢谢!【参考方案2】:

C# 有值类型和引用类型的概念。值类型“像整数一样” - 值类型的变量实际上存储值,并且它有一个默认值(通常是某种零)。

另一方面,引用类型是对内存中某些内容的引用,引用类型的变量不存储实际对象,而是存储实际对象的地址。如果你还没有初始化它,引用类型变量默认为零,也就是 null。

Vector3 是一个值类型。 List 是一种引用类型。这解释了不同的行为,以及为什么您的第二个 List 示例有效 - 在这种情况下,您已明确创建并初始化列表对象并将引用指向它。

这也是为什么一般来说,在 List 属性上使用 set 方法是个坏主意。你不想让外部调用者完全改变它指向的列表,你想改变你已经拥有的实际列表的内容。

【讨论】:

我喜欢你的回答,除了声明“引用类型变量默认为零”。它默认为特殊值null,而不是0。在 C# 中说零也称为 null 是不正确的。 嗯,在存储在 RAM 中的底层二进制值中,null 实际上是零。把它归结为我当时是一个老 C 家伙。 :-) 话虽如此,我确实理解你的观点。我试图绘制值类型的默认值(全为零)和引用类型的默认值(null,道德上的零等价物)之间的相关性。

以上是关于为啥我不能将自动实现的 getter 和 setter 与 List 一起使用? (统一,C#)的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能为 CDTVC 中的私有 UIRefreshControl 属性创建 Getter?

@synthesize @dynamic 的区别

自动实现的 getter 和 setter 与公共字段

为啥 GSON 使用字段而不是 getter/setter?

OC-分类

Lombok 写一个@Data更好还是@Getter+@Setter更好?