When my object is no longer referenced why do its events continue to run?

Posted by Ryan Peschel on Stack Overflow See other posts from Stack Overflow or by Ryan Peschel
Published on 2012-11-18T04:10:16Z Indexed on 2012/11/18 5:00 UTC
Read the original article Hit count: 129

Say I am making a game and have a base Buff class. I may also have a subclass named ThornsBuff which subscribes to the Player class's Damaged event.

The Player may have a list of Buffs and one of them may be the ThornsBuff. For example:

Test Class

Player player = new Player();
player.ActiveBuffs.Add(new ThornsBuff(player));

ThornsBuff Class

public ThornsBuff(Player player)
{
    player.DamageTaken += player_DamageTaken;
}

private void player_DamageTaken(MessagePlayerDamaged m)
{
    m.Assailant.Stats.Health -= (int)(m.DamageAmount * .25);
}

This is all to illustrate an example. If I were to remove the buff from the list, the event is not detached. Even though the player no longer has the buff, the event is still executed as if he did.

Now, I could have a Dispel method to unregister the event, but that forces the developer to call Dispel in addition to removing the Buff from the list. What if they forget, increased coupling, etc.

What I don't understand is why the event doesn't detatch itself automatically when the Buff is removed from the list. The Buff only existed in the list and that is its one reference. After it is removed shouldn't the event be detached?

I tried adding the detaching code to the finalizer of the Buff but that didn't fix it either. The event is still running even after it has 0 references. I suppose it is because the garbage collector had not run yet? Is there any way to make it automatic and instant so that when the object has no references all its events are unregisted?

Thanks.

© Stack Overflow or respective owner

Related posts about c#

Related posts about events