2
if (!someList.Contains(new listItem(arg1, args2)))
{
    // Do some stuff
}

上記のコード セグメントでsomeListは、 は構造体のリストであり、listItemは構造体です。

このコンテキストで new 演算子を使用すると、メモリ リークが発生しますか? それとも、これは一般的な悪い習慣の例ですか? SOとGoogleで検索しましたが、これに具体的に対処する質問を見つけることができませんでした.

4

4 に答える 4

6

C#でメモリリークを作成するには、本当に一生懸命働く必要があります。可能ですが、偶然に発生することはあまりありません(このような単純なメモリ管理を備えていない他の言語と相互運用する場合を除きます)。ただし、ここではエッジケースについては説明しません。

そのオブジェクトのメモリは次のようになります。

  • ローカル変数は、表示したコードを保持するメソッドで作成されます。新しい構造をローカル変数に明示的に設定しなかったため、コードで参照できない名前が付けられます。
  • スタックを介して、呼び出すメソッドに渡されます。(値によって渡されるため、この時点で同じ構造を持つ2つの変数があります)。
  • Contains返されると、呼び出しスタックのパラメータが「解放」されるため、変数が1つだけに戻ります。
  • 現在使用しているメソッドが終了すると(または、コンパイラーが使用されなくなったことを認識して最適化する場合は、少し早く)、構造体のスタックスペースが「解放」されます。

newキーワードが使用されていても、構造はヒープ上に作成されません。それはまだスタック上に作成されています。C#ではnew、コンストラクターを明示的に呼び出すときに使用され(リフレクションを除く)、ヒープへの割り当てを示しません(たとえば、C ++での方法)。

これが構造ではなくクラスであったとしても、メモリリークが発生しないことにも言及する価値があります。オブジェクトは最終的にヒープ上に配置されますが、ガベージコレクターは、不要になった後のある時点でオブジェクトのクリーンアップを処理します。ここでは、必要がなくなったオブジェクトへの参照を保持するようなことは何もしていません(そして、オブジェクトのContains収集を妨げるようなシェナニガンは実行されないことを私は知っています。それが未知の関数である場合は、可能ですが、彼らが何か意味のあることをする可能性は低いです)。

于 2012-08-31T18:10:53.357 に答える
3

構造体に関係することは珍しくありません。たとえば、DateTimes を使用する場合、次のようにすると読みやすくなります。

if (fooDate == new DateTime(2000, 1, 30, 11, 30, 0))

よりも

if (fooDate.Year = 2000 && fooDate.Month = 1 && fooDate.Day = 30 && ...)
于 2012-08-31T18:18:37.540 に答える
2

これはメモリ リークではなく、悪いスタイルと呼ぶ必要もありません (MSDN の使用例で使用されています) 。

しかし、おそらく私はそれを行う方法ではありません-私は次のようなことをします:

if (!someList.Any(o => o.Arg1 == arg1 && o.Arg2 == arg2)) 
{ 
    // Do some stuff 
} 
于 2012-08-31T18:05:12.053 に答える
1

読みやすさの問題です。あなたが示したようにすると、読みにくくなります。リストの別の宣言を好む

パフォーマンスやメモリリークに違いはありません

また、リストを個別に宣言するときに、リストに意味のある名前を付けることができます

例 var listOfDays = new List.....

于 2012-08-31T18:02:30.257 に答える