C# 类设计 - 公开变量以供读取但不能设置

发布于 2024-08-30 14:20:54 字数 613 浏览 8 评论 0原文

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

我目前正在通过此字段公开顶点:

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

但是您可以使用以下代码更改任何顶点:

Polygon1.Vertices[0] = new Vector2(0, 0);

Polygon1.Vertices[0].X = 0;

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

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

谢谢。

I have a a polygon class which stores a list of Microsoft.Xna.Framework.Vector2 as the vertices of the polygon. Once the polygon is created, I'd like other classes to be able to read the position of the vertices, but not change them.

I am currently exposing the vertices through this field:

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

However you can change any vertex using code like:

Polygon1.Vertices[0] = new Vector2(0, 0);

or

Polygon1.Vertices[0].X = 0;

How can I limit other classes to be able to only read the properties of these vertices, and not be able to set a new one to my List? The only thing I can think of is to pass a copy to classes that request it.

Note that Vector2 is a struct that is part of the XNA framework and I cannot change it.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

雨落□心尘 2024-09-06 14:20:54

在您的类型上有一个只读接口(但是因为这是内置类型),并在 ReadOnlyCollection 用于。

public ReadOnlyCollection<IReadOnlyVector2> Vertices
{
    get { return (from v in _vertices 
                  select new DerivedVector2 { WrappedVector2 = v })
                 .Cast<IReadOnlyVector2>().ToList().AsReadOnly(); 
     }
}
List<Vector2> _vertices;

interface IReadOnlyVector2 {
 .. only RO getters and no setters
}

class DerivedVector2 : IReadOnlyVector2{
    public Vector2 WrappedVector2 { get; internal set;} 
.
.
.

}

Have a readonly interface on your type (however since this is built in type), and pass out a version in a ReadOnlyCollection is for.

public ReadOnlyCollection<IReadOnlyVector2> Vertices
{
    get { return (from v in _vertices 
                  select new DerivedVector2 { WrappedVector2 = v })
                 .Cast<IReadOnlyVector2>().ToList().AsReadOnly(); 
     }
}
List<Vector2> _vertices;

interface IReadOnlyVector2 {
 .. only RO getters and no setters
}

class DerivedVector2 : IReadOnlyVector2{
    public Vector2 WrappedVector2 { get; internal set;} 
.
.
.

}

趴在窗边数星星i 2024-09-06 14:20:54

像 XNA 框架经常做的那样:

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

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

Do as the XNA Framework often does:

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

public Vector2[] Vertices { get { return myVectors.ToArray(); } }
扬花落满肩 2024-09-06 14:20:54

只是想提供 Preets 的变体回答

public IEnumerable<IReadOnlyVector2> Vertices
{
    get
    {
        return from v in _vertices 
               select (IReadOnlyVector2)new DerivedVector2(v);
    }
}

返回 IEnumerable 本质上是只读的,因为客户端只能枚举,而不能更改。此外,简化的 LINQ 表达式删除了在我看来是多余的三个额外步骤。

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

Just wanted to offer a variation on Preets answer.

public IEnumerable<IReadOnlyVector2> Vertices
{
    get
    {
        return from v in _vertices 
               select (IReadOnlyVector2)new DerivedVector2(v);
    }
}

Returning an IEnumerable<> is inherently read-only since clients can only enumerate, not change. Also, the simplified LINQ expression removes the three additional steps which imo is superfluous.

It is worth mentioning the effect of .ToList(). It will create a new instance of List<> and copy all vectors into that list. A side effect of this is that clients storing the reference will have a list that is effectively out of sync with the original. On the other hand, if we return the LINQ expression directly, enumerating the reference returned will always enumerate the internal list.

安稳善良 2024-09-06 14:20:54

还有另一种变体,使用yield:

List<Vector2> _vertices;
public IEnumerable<Vector2> Vertices
{
    get
    {
        foreach (Vector2 vec in _vertices)
            yield return vec;
    }
}

虽然我可能会说 Krisc 的答案是最好的......

当然在 _vertices.AsReadOnly() 旁边:D

Yet another variation, using yield:

List<Vector2> _vertices;
public IEnumerable<Vector2> Vertices
{
    get
    {
        foreach (Vector2 vec in _vertices)
            yield return vec;
    }
}

Although i'd probably say Krisc's answer is best...

Next to _vertices.AsReadOnly() of course :D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文