C# C类设计-为读取而非设置公开变量

C# C类设计-为读取而非设置公开变量,c#,xna,class-design,C#,Xna,Class Design,我有一个多边形类,它将Microsoft.Xna.Framework.Vector2的列表存储为多边形的顶点。创建多边形后,我希望其他类能够读取顶点的位置,但不能更改它们 我当前正在通过此字段显示顶点: /// <summary> /// Gets the vertices stored for this polygon. /// </summary> public List<Vector2> Vertices { get { return _vert

我有一个多边形类,它将Microsoft.Xna.Framework.Vector2的列表存储为多边形的顶点。创建多边形后,我希望其他类能够读取顶点的位置,但不能更改它们

我当前正在通过此字段显示顶点:

/// <summary>
/// Gets the vertices stored for this polygon.
/// </summary>
public List<Vector2> Vertices
{
    get { return _vertices; }
}
List<Vector2> _vertices;

如何限制其他类只能读取这些顶点的属性,而不能在列表中设置新的顶点?我唯一能想到的就是将副本传递给请求它的类

请注意,Vector2是XNA框架的一部分,我无法更改它


谢谢。

在您的类型上有一个只读接口,但是因为这是内置类型,所以在中分发一个版本是为了


}

在您的类型上有一个只读接口,但是因为这是内置类型,所以在中分发一个版本是为了


}

像XNA框架通常做的那样:

private List<Vector2> myVectors = new List<Vector2>();

public Vector2[] Vertices { get { return myVectors.ToArray(); } }

按照XNA框架通常的做法:

private List<Vector2> myVectors = new List<Vector2>();

public Vector2[] Vertices { get { return myVectors.ToArray(); } }

只是想提供一个变化

返回IEnumerable本身就是只读的,因为客户端只能枚举,不能更改。此外,简化的LINQ表达式删除了imo多余的三个附加步骤


值得一提的是,托利斯的影响。它将创建列表的新实例,并将所有向量复制到该列表中。这样做的一个副作用是,存储引用的客户端将有一个实际上与原始列表不同步的列表。另一方面,如果我们直接返回LINQ表达式,则枚举返回的引用将始终枚举内部列表。

只是想提供一个变量

返回IEnumerable本身就是只读的,因为客户端只能枚举,不能更改。此外,简化的LINQ表达式删除了imo多余的三个附加步骤


值得一提的是,托利斯的影响。它将创建列表的新实例,并将所有向量复制到该列表中。这样做的一个副作用是,存储引用的客户端将有一个实际上与原始列表不同步的列表。另一方面,如果我们直接返回LINQ表达式,枚举返回的引用将始终枚举内部列表。

另一种变体,使用yield:

List<Vector2> _vertices;
public IEnumerable<Vector2> Vertices
{
    get
    {
        foreach (Vector2 vec in _vertices)
            yield return vec;
    }
}
虽然我可能会说Krisc的答案是最好的


当然,除了_vertices.AsReadOnly:D

还有另一个变体,使用收益率:

List<Vector2> _vertices;
public IEnumerable<Vector2> Vertices
{
    get
    {
        foreach (Vector2 vec in _vertices)
            yield return vec;
    }
}
虽然我可能会说Krisc的答案是最好的


当然,在_vertices.AsReadOnly旁边:D

调用_vertices.AsReadOnly通常是首选。我不知道!谢谢如果您调用Cast,您实际上可以公开IEnumerable,前提是该接口具有您需要的功能。Cast函数有效地将原始列表与消费代码隔离开来,就像Enumerable.calling _vertices.AsReadOnly上的任何其他转换函数一样。通常首选调用_vertices.AsReadOnly。我不知道这一点!谢谢如果您调用Cast,您实际上可以公开IEnumerable,前提是该接口具有您需要的功能。Cast函数有效地将原始列表与使用代码隔离开来,就像Enumerable上的任何其他转换函数一样。
public IEnumerable<IReadOnlyVector2> Vertices
{
    get
    {
        return from v in _vertices 
               select (IReadOnlyVector2)new DerivedVector2(v);
    }
}
List<Vector2> _vertices;
public IEnumerable<Vector2> Vertices
{
    get
    {
        foreach (Vector2 vec in _vertices)
            yield return vec;
    }
}