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 への変更以外に、他に何をお勧めしますか? 私の現在のアプリがメモリをリークしていることに気付きました:(

ありがとう;

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

どちらのアプローチも、プロパティを 1 回だけ呼び出します。2番目はより明確なIMOです。

他の考え; メソッドと名付けましょう!つまり、これは機能するという期待を設定し、望ましくないこと (配列の場合) を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

コストのかかるプロパティ (呼び出し時にコレクションを再作成するなど) がある場合は常に、プロパティをドキュメント化して、各呼び出しにコストがかかることを示すか、値をプライベート フィールドとしてキャッシュします。コストのかかるプロパティ ゲッターは、メソッドとして記述する必要があります。通常、私はコレクションを配列ではなく IEnumerable として公開し、コンシューマーに foreach (または列挙子) を使用させようとします。

于 2009-01-04T10:35:45.493 に答える
0

作成しない限り、配列のコピーは作成されません。ただし、オブジェクトによってプライベートに所有されている配列への参照を渡すだけでは、いくつかの厄介な副作用があります。参照を受け取った人は基本的に、その所有者が制御できない方法で内容を変更するなど、配列に対して好きなことを自由に行うことができます。

配列への無許可の干渉を防ぐ 1 つの方法は、内容のコピーを返すことです。もう 1 つの (少し良い) 方法は、読み取り専用のコレクションを返すことです。

それでも、これらのことを行う前に、あまりにも多くの情報を提供しようとしていないかどうかを自問する必要があります. 場合によっては (実際にはかなり頻繁に)、配列を非公開にしておき、その代わりにそれを所有するオブジェクトを操作するメソッドを提供する方がよい場合もあります。

于 2009-01-04T10:47:35.127 に答える
0

myobj は、明示的にアイテムを作成しない限り、新しいアイテムを作成しません。したがって、メモリ使用量を改善するには、プライベート コレクション (リストまたは任意) を使用し、プライベート コレクションから指定された値を返すインデクサーを公開することをお勧めします

于 2009-01-04T10:56:00.133 に答える