3

私はC#で弱参照がどのように機能するかを学ぶのに時間を費やしていて、この奇妙な振る舞いに出くわしました。

以下のサンプルコードでは、最初のテストは成功し、2番目のテストは失敗します。構築後、弱参照を作成する前に、オブジェクトのインスタンスを変更することはできないようです。ただし、弱参照が期待どおりに機能するのを停止する必要はありません。

private class Simple
{
    public Simple() { X = "Hello"; }
    public string X { get; set; }
}

[Test]
public void CreatingWeakReferenceBeforeModifying()
{
    var a = new Simple();
    var aRef = new WeakReference(a);
    a.X = "World";  // First modification to a after creating reference
    a = null;
    GC.Collect();
    Assert.That(aRef.IsAlive, Is.False);  // This assertion passes
}

[Test]
public void CreatingWeakReferenceAfterModifying()
{
    var b = new Simple {X = "World"};  // First mod to b before creating ref
    var bRef = new WeakReference(b);
    b = null;
    GC.Collect();
    Assert.That(bRef.IsAlive, Is.False);  // This assertion fails
}

私はここで何かを逃したことがありますか?

4

1 に答える 1

4

これは特定の状況でのみ表示されると思います。特に、デバッグビルド、特にデバッガーで発生する可能性があります

この文:

var b = new Simple {X = "World"};

効果的に:

var tmp = new Simple();
tmp.X = "World";
var b = tmp;

したがってb、nullに設定している場合でも、オブジェクトへの参照を持つローカル変数がスタックにあります。

最適化されたシナリオで実行する場合、ローカル変数が二度と読み取られないことにGCが気づき、それをGCルートとして無視することを期待しますが、実行方法でGCがそのようにならない可能性があります攻撃的。

于 2012-11-16T11:25:28.367 に答える