.NET の一意のオブジェクト識別子 質問する

.NET の一意のオブジェクト識別子 質問する

インスタンスの一意の識別子を取得する方法はありますか?

GetHashCode()同じインスタンスを指す 2 つの参照は同じです。ただし、2 つの異なるインスタンスが (非常に簡単に) 同じハッシュ コードを取得する可能性があります。

Hashtable hashCodesSeen = new Hashtable();
LinkedList<object> l = new LinkedList<object>();
int n = 0;
while (true)
{
    object o = new object();
    // Remember objects so that they don't get collected.
    // This does not make any difference though :(
    l.AddFirst(o);
    int hashCode = o.GetHashCode();
    n++;
    if (hashCodesSeen.ContainsKey(hashCode))
    {
        // Same hashCode seen twice for DIFFERENT objects (n is as low as 5322).
        Console.WriteLine("Hashcode seen twice: " + n + " (" + hashCode + ")");
        break;
    }
    hashCodesSeen.Add(hashCode, null);
}

デバッグ アドインを作成していますが、プログラムの実行中に一意となる参照用の何らかの ID を取得する必要があります。

インスタンスの内部アドレスをすでに取得できました。このアドレスは、ガベージ コレクター (GC) がヒープを圧縮する (= オブジェクトを移動する = アドレスを変更する) まで一意です。

スタックオーバーフローの質問Object.GetHashCode() のデフォルト実装関連している可能性があります。

デバッガー API を使用してデバッグ中のプログラム内のオブジェクトにアクセスしているため、オブジェクトは私の制御下にありません。私がオブジェクトを制御できる場合、独自の一意の識別子を追加するのは簡単です。

ハッシュテーブル ID -> オブジェクトを構築して、既に表示されているオブジェクトを検索できるようにするための一意の ID が必要でした。今のところ、次のように解決しました。

Build a hashtable: 'hashCode' -> (list of objects with hash code == 'hashCode')
Find if object seen(o) {
    candidates = hashtable[o.GetHashCode()] // Objects with the same hashCode.
    If no candidates, the object is new
    If some candidates, compare their addresses to o.Address
        If no address is equal (the hash code was just a coincidence) -> o is new
        If some address equal, o already seen
}

ベストアンサー1

.NET 4 以降のみ

皆さん、朗報です!

この作業に最適なツールは.NET 4に組み込まれており、ConditionalWeakTable<TKey, TValue>。 このクラス:

  • 辞書のように任意のデータを管理対象オブジェクトのインスタンスに関連付けるために使用できます(ただし、辞書ではありません)
  • メモリアドレスに依存しないため、GCによるヒープの圧縮の影響を受けない
  • オブジェクトがキーとしてテーブルに入力されたからといって、そのオブジェクトを存続させるわけではないので、プロセス内のすべてのオブジェクトを永久に存続させることなく使用できます。
  • 参照の等価性を使用してオブジェクトのアイデンティティを決定します。クラスの作成者はこの動作を変更できないため、一貫してあらゆるタイプのオブジェクトに
  • オンザフライで設定できるため、オブジェクトコンストラクタ内にコードを挿入する必要はありません。

おすすめ記事