用語を混同しないでください。C#にはポインターがありますが、それはあなたが持っているものではありません。参照があります。重要なことに、参照はガベージコレクターに影響を与えますが、ポインター自体は影響を与えません。(*)
のインスタンスFoo
が到達可能である限り、への参照bar
はそのオブジェクトも到達可能に保ちます。ファイナライザーがある場合Foo
、Bar
ファイナライザーでFoo
は、何も想定してはいけない状況が1つありますbar
。これは、すでにファイナライズされている可能性があります。
ご指摘のとおり、アクセスする他のメソッドは呼び出されbar
ませんが、GCとJITはこの種の分析を実行しません。オブジェクト参照の場合、オブジェクト全体が到達可能であると見なされ、オブジェクトに含まれるすべての参照が追跡され、同様に配置されたオブジェクトが到達可能としてマークされます。これは、オブジェクトへのリフレクションベースのアクセスが無効な参照を取得しないようにするために行う必要があります。これは、オブジェクトが、使用しなくなる大きなヘルパーオブジェクトを割り当てた場合に、(この限られた状況で)参照をに設定すると便利な場合がある理由でもありますnull
。
将来のコードが実行されるかどうかを考慮する唯一のライフタイム分析は、ローカル変数に関して、単一のメソッド本体内のコードです。メソッド内のローカル参照変数は、その変数へのそれ以上の参照が発生しない場合、オブジェクトを存続させるのに十分ではありません。これは、JITとGCの間で共同で解決されます。
(*)人々は、ポインタがオブジェクトを存続させると考えることがあります。これは厳密には真実ではありません。ポインターを生成できるピン留めの動作は、オブジェクトを存続させますが、オブジェクトがピン留めされた時間を超えてポインターを保持することを妨げるものは何もありません。もちろん、そのようなときにポインタを参照解除することは安全ではありません...
そして、別の用語の問題:
GCがバーを処分することを許可されているかどうか疑問に思います
GCは何も処理しません。廃棄は、オブジェクトがIDisposableを実装し、オブジェクトのユーザーがDispose
(直接またはusing
ブロックなどを介して)それを呼び出すときに発生します。
GCはを呼び出しませんDispose
。ファイナライザーがオブジェクトに定義されている場合(したがって、上記の警告が適用される場合)、ファイナライザーを呼び出して、オブジェクトを収集する場合があります。