拥有许多发布商的订阅者:取消订阅

我希望这不是太一般,所以我提前道歉,如果是的话。 我正在创建一个控制台文本冒险游戏。 我基本上有许多怪物,现在每个房间一个。 我也有一个上帝的对象/类,它实质上是监视这些怪物,看它们是否死亡。 我在怪物类中有一个静态事件处理程序(“HealthEventHandler”),我使用它来向事件添加方法。 当一个怪物的死亡旗帜变为真实时,一个怪物的方法被称为增加一个上帝来观看这个怪物(IsWatching列表)。 当怪物死亡时,一旦死亡标志被翻转为真,死亡检定就会被触发。 应该从事件(?)处理程序中删除OnDeath的实例,因为怪物应该只被牺牲一次(DeathCheck – = this.OnDeath;)。 这是在这样的情况下取消订阅的正确方法吗? 对于这里的糟糕解释,我也很抱歉,这就是为什么我列出了所有相关的代码,以帮助您了解我做得更好。

我遇到的潜在问题是,有时这些事件似乎会发生两次。 例如,我杀了一个怪物,上帝接受了这个牺牲,然后继续杀死另一个怪物,上帝接受了这个新的牺牲品和应该已经牺牲的怪物。 我显然在这里错过了一些重要的东西,或者走错了路。 任何指导在这里将不胜感激如何我可以实现这个事件系统。 我只是在寻找一个怪物去世的时候,上帝会接受这个牺牲,并且用一些黄金奖励玩家。

怪物类:

public class monster { public static player _player; private delegate void HealthEventHandler(player _player); private static HealthEventHandler DeathCheck; private List<God> IsWatching = new List<God>(); public bool sacrificed = false; public bool _dead; public bool dead { get { return _dead; } set { if (DeathCheck != null) { if (value == true) { _dead = true; if (this.sacrificed == false) { DeathCheck.Invoke(monster._player); DeathCheck -= this.OnDeath; } } else { _dead = value; } } else { _dead = value; } } } public monster(int _level, string _name) { DeathCheck += new HealthEventHandler(this.OnDeath); level = _level; name = _name; } public void DeathWatch(God _god) { IsWatching.Add(_god); } public void OnDeath(player _player) { foreach (God g in IsWatching) { g.TakeSoul(this, _player); } this.sacrificed = true; } } 

上帝类:

 public class God { public string name; public int soulCount; public ConsoleColor color = ConsoleColor.White; public God(string _name, string _color) { name = _name; soulCount = 0; if (_color == "blue" || _color == "Blue") { color = ConsoleColor.Blue; } else if (_color == "red" || _color == "Red") { color = ConsoleColor.Red; } else if (_color == "yellow" || _color == "Yellow") { color = ConsoleColor.Yellow; } } public void TakeSoul(monster _monster, player _player) { System.Threading.Thread.Sleep(200); Console.WriteLine("\n {0} contemplates whether to accept your offer...\n ", this.name); System.Threading.Thread.Sleep(600); Console.Write("\n {0} decides to accept the soul of {1}!", this.name, _monster.name); Console.WriteLine(" + {0} gp.\n", (_monster.level * 123)); _player.gp += _monster.level * 123; } }