When my object is no longer referenced why do its events continue to run?
- by Ryan Peschel
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.