我为什么可以.将 () 添加到一个列表,该列表是一个只有一个 get 访问器的属性
本文关键字:列表 一个 get 有一个 访问 属性 添加 为什么 | 更新日期: 2023-09-27 18:33:46
我正在遵循有关程序生成网格的教程,我想知道为什么可以.Add() 到一个 List,当该列表只有一个 get 访问器时,该列表是一个类的属性。 我是 C# 的新手,我在这里错过了什么?
例如,本教程让用户编写此类:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MeshBuilder
{
private List<Vector3> m_Vertices = new List<Vector3>();
public List<Vector3> Vertices { get { return m_Vertices; } }
private List<Vector3> m_Normals = new List<Vector3>();
public List<Vector3> Normals { get { return m_Normals; } }
private List<Vector2> m_UVs = new List<Vector2>();
public List<Vector2> UVs { get { return m_UVs; } }
private List<int> m_Indices = new List<int>();
public void AddTriangle(int index0, int index1, int index2)
{
m_Indices.Add(index0);
m_Indices.Add(index1);
m_Indices.Add(index2);
}
public Mesh CreateMesh()
{
Mesh mesh = new Mesh();
mesh.vertices = m_Vertices.ToArray();
mesh.triangles = m_Indices.ToArray();
//Normals are optional. Only use them if we have the correct amount:
if (m_Normals.Count == m_Vertices.Count)
mesh.normals = m_Normals.ToArray();
//UVs are optional. Only use them if we have the correct amount:
if (m_UVs.Count == m_Vertices.Count)
mesh.uv = m_UVs.ToArray();
mesh.RecalculateBounds();
return mesh;
}
}
然后我们编写另一个使用该类的脚本:
using UnityEngine;
using System.Collections;
public class ProcQuad : MonoBehaviour {
float m_Width = 1;
float m_Length = 1;
// Use this for initialization
void Start () {
MeshBuilder meshBuilder = new MeshBuilder();
//set up vertices and triangles
meshBuilder.Vertices.Add (new Vector3(0.0f, 0.0f, 0.0f));
meshBuilder.UVs.Add(new Vector2(0.0f, 0.0f));
meshBuilder.Normals.Add(Vector3.up);
meshBuilder.Vertices.Add(new Vector3(0.0f, 0.0f, m_Length));
meshBuilder.UVs.Add(new Vector2(0.0f, 1.0f));
meshBuilder.Normals.Add (Vector3.up);
meshBuilder.Vertices.Add(new Vector3(m_Width, 0.0f, m_Length));
meshBuilder.UVs.Add(new Vector2(1.0f, 1.0f));
meshBuilder.Normals.Add(Vector3.up);
meshBuilder.Vertices.Add (new Vector3(m_Width, 0.0f, 0.0f));
meshBuilder.UVs.Add(new Vector2(1.0f, 0.0f));
meshBuilder.Normals.Add(Vector3.up);
meshBuilder.AddTriangle(0, 1, 2);
meshBuilder.AddTriangle(0, 2, 3);
MeshFilter filter = GetComponent<MeshFilter>();
if (filter != null)
{
filter.sharedMesh = meshBuilder.CreateMesh();
}
}
// Update is called once per frame
void Update () {
}
}
那么为什么我们能够执行:
meshBuilder.Vertices.Add (new Vector3(0.0f, 0.0f, 0.0f));
为什么当属性 Vertices 只有一个 get 访问器时,它会修改私有字段m_Vertices?
public List<Vector3> Vertices { get { return m_Vertices; } }
感谢您的见解。
如果有人对本教程感兴趣,我在这里找到了它:
http://jayelinda.com/wp/modelling-by-numbers-part-1a/
由于 Add
方法属于 List<T>
类,因此只需调用它即可引用列表对象。有一个 getter 来提供引用就足够了,因为您不需要分配一个新列表,只需要获取一个现有列表。
如果要禁止添加,请将 getter 更改为返回 AsReadOnly()
,如下所示:
public List<Vector3> Vertices { get { return m_Vertices.AsReadOnly(); } }
请注意,Add()
的调用将进行编译,但由于在运行时列表是只读的,因此在调用 Add()
方法时将引发异常。
您无法set
列表的事实意味着这会给您一个编译错误:
meshBuilder.Vertices = new List<Vector3>(); //Not allowed! You're assigning to a list that you can't set
但是根据您那里的代码,get
列表m_Vertices
并向其中添加项目(就像任何其他List
一样)是完全合法的,因为您不会为Vertices
分配新的List
。
get
访问器返回对List<T>
的引用。获得对该引用后,您可以在该List<T>
上调用任何方法。
缺少set
访问器会阻止您用另一个List<T>
替换List<T>
。这是列表或集合属性的常见做法,以确保这些属性永远不会返回 null