こんにちは。
この質問に回答する前に、まず「リソースとは何か」を明確にする必要があります。
リソースというものを「明確な開始宣言と終了宣言をペアで扱う必要があるもの」と定義すると、IDisposableなオブジェクト(usingで使えるもの)はまさしくリソースですが、逆に配列やリストは「それはリソースではない」ということになり、この質問の前提が成り立っていないことになります。
実際、リソースを「明示的な破棄が必要なもの」と言い換えたとき、配列やリストは「破棄するものではない」ということが分かると思います。仮に配列に「リソース」を詰めた場合であっても、破棄するべきはその要素であって、配列そのものではないのです。
と、ここまでの回答は置いといて、
インスタンス化したオブジェクト(リソースではない)が解放されるのは、プログラムコード的には「コードのどこからも辿れなくなったとき」です。つまりは、質問の通りelse句が終わって配列にアクセスできなくなった時点で「そのオブジェクトは解放された」と考えてしまって問題ないです。何故なら、誰もアクセスできなくなったオブジェクトは存在していないのと同意だからです。
そして、ランタイム的には「コードのどこからも辿れなくなったあと、任意のタイミング」で解放されます。これは.NETのランタイムで動作しているGCによるもので、プログラム的に「解放された」オブジェクトは、任意のタイミングでGCの手により実際にメモリ上から削除されます。このような2段構えにしている理由は、メモリ管理の自動化を現実的に可能にする手法の一つだったからです。
結局のところ、
C#のオブジェクトは「実質的に解放したと言える」であれば問題ないことがほとんどです。そのようなオブジェクトであれば、「メモリの管理はランタイムにお任せ」ができるため、プログラマの負担が大幅に減ります。しかし、どうしてもそれでは足りない存在を扱うために「リソース」という概念が生まれ、リソースを扱うためのusingという構文が生まれた、という、順序が逆なのです。
質問への回答として、
配列やリストはコードブロックを抜けたら「実質的に解放」と考え、その実際のメモリ領域は「コード的に解放してあれば、いつか勝手に削除される」というものと考えておけば問題ありません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/07/08 03:59