根据[MSDN:阵列使用指南](http://msdn.microsoft.com/en-us/library/k2604h5s(VS.71).aspx):
数组值属性
您应该使用集合来避免代码效率低下。在下面的代码示例中,每次调用myObj属性都会创建一个数组副本。因此,将在以下循环中创建2n + 1个数组副本。
[Visual Basic]
Dim i As Integer
For i = 0 To obj.myObj.Count - 1
DoSomething(obj.myObj(i))
Next i
[C#]
for (int i = 0; i < obj.myObj.Count; i++)
DoSomething(obj.myObj[i]);
除了从myObj []更改为ICollection myObj之外,您还会推荐什么?刚刚意识到我当前的应用程序正在泄漏内存:(
感谢;
编辑:强制C#传递引用w / ref(安全性除外)会提高性能和/或内存使用率吗?
答案 0 :(得分:5)
不,它不是泄漏内存 - 它只是让垃圾收集器比它可能更难工作。实际上,MSDN文章有点误导:如果属性在每次调用时都创建了一个新的集合,那么它与数组一样糟糕(内存方面)。也许更糟糕的是,由于大多数集合实现通常过大。
如果您知道方法/属性确实有效,您始终可以最小化呼叫次数:
var arr = obj.myObj; // var since I don't know the type!
for (int i = 0; i < arr.Length; i++) {
DoSomething(arr[i]);
}
甚至更简单,请使用foreach
:
foreach(var value in obj.myObj) {
DoSomething(value);
}
两种方法只调用一次属性。第二个是更清晰的IMO。
其他想法;把它命名为方法!即obj.SomeMethod()
- 这设置了它确实有效的期望,并避免了不受欢迎的obj.Foo != obj.Foo
(对于数组来说就是这种情况)。
最后,Eric Lippert有一个很好的article on this subject。
答案 1 :(得分:2)
正如那些没有使用某些答案中提到的ReadOnlyCollection的人的暗示:
[C#]
class XY
{
private X[] array;
public ReadOnlyCollection<X> myObj
{
get
{
return Array.AsReadOnly(array);
}
}
}
希望这可能有所帮助。
答案 2 :(得分:1)
每当我有昂贵的属性(比如在电话中重新创建集合)时,我要么记录属性,说明每次调用都会产生成本,或者我将值缓存为私有字段。昂贵的财产获取者应该作为方法编写。 通常,我尝试将集合公开为IEnumerable而不是数组,迫使消费者使用foreach(或枚举器)。
答案 3 :(得分:0)
除非您这样做,否则它不会复制数组。但是,简单地将引用传递给对象私有的数组会产生一些令人讨厌的副作用。收到参考资料的人基本上可以自由地对阵列做任何他喜欢的事情,包括以其所有者无法控制的方式改变内容。
防止未经授权干扰阵列的一种方法是返回内容的副本。另一个(稍微好一点)是返回一个只读集合。
但是,在做这些事情之前,你应该问问自己是否要泄露太多信息。在某些情况下(实际上,经常),最好保持数组私有,而是提供对拥有它的对象进行操作的方法。
答案 4 :(得分:0)
除非您明确创建新项目,否则myobj不会创建新项目。为了更好地使用内存,我建议使用私有集合(List或any)并公开将从私有集合中返回指定值的索引器