夕方にリヒターを読んだ後、私はそれぞれの詳細をより詳細に理解することに決めました。 本のページをスクロールすると、毎日設計され、書かれているものの多くが、.Netの基盤の一部に常に違反しているという結論に達しました。
構造とコレクションの例を考えてみましょう。 構造は値型であり、参照構造とは異なる動作をすることを思い出しません。
例1.古いArrayListを使用します。
System.Int32 myInt = 7; ArrayList al = new ArrayList(); al.Add(myInt);
期待される結果は、System.Int32型のスタックに2つの異なる要素が存在することです。 さらに、そのうちの1つは既に参照型になります。 このコードのIL表現を開くと、公正な確認が表示されます。
IL_0002:stloc.0 // myInt IL_0003:newobj System.Collections.ArrayList..ctor IL_0008:stloc.1 // al IL_0009:ldloc。1 // al IL_000A:ldloc.0 // myInt IL_000B:ボックスSystem.Int32 IL_0010:callvirt System.Collections.ArrayList.Add
ボックス(ボクシング)操作は、Int32型のヒープ上にオブジェクトを作成します。 タイプの構造の要素を追加すると、そのアナログがヒープ上に作成されるたびに、リンクがコレクションに分類されます。 時間が経つにつれて、一般的なコレクションが助けになりました。 例とそのIL表現を検討してください。
例2.コレクションの一般化の使用:
System.Int32 myInt = 7; List<int> l = new List<int>(); l.Add(myInt);
このコードは次のように変換されます。
IL_0002:stloc.0 // myInt IL_0003:newobj System.Collections.Generic.List..ctor IL_0008:stloc.1 // l IL_0009:ldloc。1 // l IL_000A:ldloc.0 // myInt IL_000B:callvirt System.Collections.Generic.List.Add
このようなコレクションはより高度であり、box \ unbox操作を使用せずに、値の型をより適切に処理できます。 これにより、メモリのオーバーヘッドが大幅に削減され、パフォーマンスが向上し、ガベージコレクションが削減されます。
しかし、しばらくの間コレクションをより詳細に実験した後、思いがけない瞬間に出会いました。 次のようなスタイルで何かを書く必要がある場合があります。
IList l =新しいリスト<T>();
コードは単純ですが、構造に対する結果は混在していました。
そのようなコードのIL表現を見ると:
System.Int32 myInt = 7; IList l = new List <int>(); l.Add(myInt);
次に、以下を取得します。
IL_0002:stloc.0 // myInt IL_0003:newobj System.Collections.Generic.List..ctor IL_0008:stloc.1 // l IL_0009:ldloc。1 // l IL_000A:ldloc.0 // myInt IL_000B:ボックスSystem.Int32 IL_0010:callvirt System.Collections.IList.Add
私たちは再び包装ユニットに落ちます。 また、ヒープ上のオブジェクトをmyInt値のコピーとして取得します。 どうやら、開発者は、特に重要な型の場合、変数の一般化の型を明示的に指定することで、コレクションオブジェクトの動作に影響を与えるような方法でコレクションを実装しました。
これが何が起こっているのかを説明しようとした最初の結論でした。 その結果、著者自身から少し後に説明が見つかりました。 インターフェイス変数は常にヒープに配置する必要があり、これにより追加のパッキング操作が表示されます。
結論は簡単です。 通常はすべてが異なる方法で発生しますが、最初に理論、次に実践します。