2009-01-04 107 views
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#通過W/REF引用(安全除外)提高性能和/或內存使用

回答

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); 
} 

這兩種方法都只能調用屬性一旦。第二個是更清晰的海事組織。

其他想法;將其命名爲一種方法!即obj.SomeMethod() - 這設定它的工作的期望,並避免不受歡迎的obj.Foo != obj.Foo(這將是陣列的情況)。

最後,Eric Lippert擁有不錯的article on this subject

+0

您還可以使屬性getter變得聰明,並緩存在調用之間返回的數組。很顯然,您需要在必要時智能地使緩存失效。 – 2009-01-04 10:30:24

1

每當我擁有昂貴的屬性(如重新創建一個集合)時,我要麼記錄屬性,說明每個調用都會產生成本,或者將該值緩存爲私有字段。屬性獲取器成本高昂,應該寫成方法。 通常,我嘗試將集合暴露爲IEnumerable而不是數組,迫使消費者使用foreach(或枚舉器)。

0

它不會複製數組,除非你這樣做。但是,簡單地將引用傳遞給由對象私有的數組會有一些令人討厭的副作用。接受參考的人基本上可以隨意做任何他喜歡的陣容,包括以其所有者無法控制的方式改變內容。

防止未經授權插入數組的一種方法是返回內容的副本。另一個(稍微好一些)是返回一個只讀集合。

不過,在做任何這些事情之前,你應該問問自己,如果你要放棄太多的信息。在某些情況下(實際上很常見),將數組保留爲私有更好,而是讓提供對擁有它的對象進行操作的方法。

0

myobj不會創建新項目,除非您明確創建一個項目。所以爲了更好地利用內存,我建議使用私有集合(List或任何),並暴露索引器,它將從私有集合中返回指定的值。

2

正如爲那些沒有使用ReadOnlyCollection的人提示的那樣的答案:

[C#] 

class XY 
{ 
    private X[] array; 

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

希望這可能有所幫助。