有没有更好的方法来封装数组?

时间:2015-10-13 15:41:48

标签: c# arrays encapsulation

我目前的表现如何:

class Foo
{
    public int[] A { get { return (int[])a.Clone(); } }
    private int[] a;
}

我认为这很糟糕,因为它会在我访问它时创建一个克隆并进行转换。我知道我可以通过引入像这样的附加变量来解决这个问题

var foo = new Foo();
// as soon as you have to access foo.A do this
int[] fooA = foo.A;
// use fooA instead of foo.A from now on

但它看起来还不错。

我也不喜欢java封装方式

int get(int index) { return a[index]; }

因为我没有使用数组的优势。

有没有更好的方法呢?

编辑:我想要一个封装变量数组。问题是

public int[] A { get; private set; }

不是封装变量数组,因为我可以从类外部修改数组元素。

编辑:它也适用于多维数组

4 个答案:

答案 0 :(得分:1)

数组实现IReadOnlyList<T>,它公开了你想要的所有相关信息(迭代器,索引器,计数等),而不暴露数组的任何可变功能。

class Foo
{
    public IReadOnlyList<int> A { get { return a; } }
    private int[] a;
}

答案 1 :(得分:0)

或者,您可以使用迭代器/生成器按要求返回项目:

class Foo
{
    public IEnumerable<int> A
    {
        get
        {
            foreach (int i in a)
                yield return i;
        }
    }
    private int[] a;
}

...然后正常迭代它们或使用LINQ将它们作为新数组或其他类型的集合:

int[] arr = foo.A.ToArray();

答案 2 :(得分:0)

为什么不将A公开为IReadOnlyList

的实现
class Foo
{
    public IReadOnlyList<int> A { get { return a; } }
    private int[] a;
}

这允许您将Array作为集合返回,他们可以使用索引但不能更改数组本身的内容。

答案 3 :(得分:-1)

听起来你需要一个索引器

...
public int this[int i]{
  get{return a[i];}
  set{a[i] = value;}
}
....

https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx