1. ホーム
  2. c#

[解決済み] C#でオブジェクトが破棄されたかどうかを確認する方法 [重複] (英語)

2023-04-06 15:40:48

質問

重複の可能性があります。

IDisposable オブジェクトの参照が破棄されたかどうかを判断するにはどうすればよいですか?

オブジェクトが廃棄されたかどうかを確認する方法はありますか?

try
{
    myObj.CallRandomMethod();
} catch (ObjectDisposedException e)
{
    // now I know object has been disposed
}

私の場合は TcpClient クラスで Close() メソッドがあり、そのメソッドはオブジェクトを破棄し、これは私がコントロールできないコードの一部で発生する可能性があります。この場合、私は例外をキャッチするよりも良い解決策を持っていることを望みます。

どのように解決するのですか?

TcpClientを派生させ、Disposing(bool)メソッドをオーバーライドするのが良い方法です。

class MyClient : TcpClient {
    public bool IsDead { get; set; }
    protected override void Dispose(bool disposing) {
        IsDead = true;
        base.Dispose(disposing);
    }
}

他のコードがインスタンスを生成した場合、これは動作しません。 その場合は、Reflectionを使ってプライベートなm_CleanedUpメンバの値を取得するなど、必死で何かしなければならないでしょう。 または例外をキャッチする。

正直なところ、どれもあまり良い結果にはなりそうもありません。 あなたは本当に した は TCP ポートに書き込みたかったのです。 しかし、あなたはそうしないでしょう。あなたがコントロールできないそのバギーコードは、現在 のコードを制御することになります。 あなたはバグの影響を増大させてしまったのです。 そのコードの所有者と話して、何かを解決することが、はるかに最良の解決策です。

EDIT: 反射の例です。

using System.Reflection;
public static bool SocketIsDisposed(Socket s)
{
   BindingFlags bfIsDisposed = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetProperty;
   // Retrieve a FieldInfo instance corresponding to the field
   PropertyInfo field = s.GetType().GetProperty("CleanedUp", bfIsDisposed);
   // Retrieve the value of the field, and cast as necessary
   return (bool)field.GetValue(s, null);
}