public void AllowsForGarbageCollection() { var mortal = new LifetimeSource(); var lifes = new[] { Lifetime.Immortal, Lifetime.Dead, mortal.Lifetime }; // callbacks are not kept when the lifetime is not mortal var f = ValidCallbackMaker; foreach (var life in lifes) { // pre-finished f.AssertCollectedAfter(e => Lifetime.Immortal.WhenDead(e, life)); f.AssertCollectedAfter(e => Lifetime.Dead.WhenDead(e, life)); f.AssertCollectedAfter(e => LimboedLifetime.WhenDead(e, life)); // post-finished f.AssertCollectedAfter(e => { using (var limbod = new LimboLife()) limbod.Lifetime.WhenDead(e, life); }); f.AssertCollectedAfter(e => { using (var blessed = new BlessedLife()) blessed.Lifetime.WhenDead(e, life); }); f.AssertCollectedAfter(e => { using (var doomed = new DoomedLife()) doomed.Lifetime.WhenDead(e, life); }); } // callbacks are not kept when the subscription lifetime is dead or dies f.AssertCollectedAfter(e => { using (var doomed = new DoomedLife()) mortal.Lifetime.WhenDead(e, doomed.Lifetime); }); f.AssertCollectedAfter(e => mortal.Lifetime.WhenDead(e, Lifetime.Dead)); // callbacks are kept when the lifetime is mortal and the subscription lifetime does not die f.AssertNotCollectedAfter(e => mortal.Lifetime.WhenDead(e, Lifetime.Immortal)); f.AssertNotCollectedAfter(e => mortal.Lifetime.WhenDead(e, mortal.Lifetime)); GC.KeepAlive(mortal); }