2

根据 [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# 传递带 ref 的引用(安全除外)会提高性能和/或内存使用吗?

4

5 回答 5

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。

其他想法; 将其命名为方法!ie obj.SomeMethod()- 这设定了它确实有效的期望,并避免了不受欢迎obj.Foo != obj.Foo的情况(数组就是这种情况)。

最后,Eric Lippert 有一篇关于这个主题的好文章

于 2009-01-04T10:16:23.350 回答
2

就像对那些没有使用某些答案中提到的 ReadOnlyCollection 的人的提示:

[C#]

class XY
{
  private X[] array;

  public ReadOnlyCollection<X> myObj
  {
    get
    {
      return Array.AsReadOnly(array);
    }
  }
}

希望这可能会有所帮助。

于 2009-01-04T12:38:15.107 回答
1

每当我拥有昂贵的属性(例如在调用时重新创建集合)时,我要么记录属性,说明每次调用都会产生成本,要么将值缓存为私有字段。昂贵的属性 getter 应该写成方法。通常,我尝试将集合公开为 IEnumerable 而不是数组,从而迫使消费者使用 foreach(或枚举器)。

于 2009-01-04T10:35:45.493 回答
0

除非您这样做,否则它不会复制数组。然而,简单地将引用传递给对象私有的数组会有一些讨厌的副作用。接收到引用的人基本上可以自由地对数组做任何他喜欢的事情,包括以无法由其所有者控制的方式更改内容。

防止未经授权干预数组的一种方法是返回内容的副本。另一个(稍微好一点)是返回一个只读集合。

尽管如此,在做任何这些事情之前,你应该问问自己是否要泄露太多信息。在某些情况下(实际上,很多时候),最好将数组保持私有,而是让提供对拥有它的对象进行操作的方法。

于 2009-01-04T10:47:35.127 回答
0

myobj 不会创建新项目,除非您明确创建一个。所以为了更好地使用内存,我建议使用私有集合(列表或任何)并公开索引器,它将从私有集合中返回指定的值

于 2009-01-04T10:56:00.133 回答