Есть два способа сделать это:
- Вы можете создать новую цепочку делегатов с удаленным отписавшимся делегатом и сравнить его с тем, который вы получили, прежде чем сохранить его. Если вы отмените подписку на делегата, у которого подписано , вы получите новую цепочку делегатов без этого делегата. В случае, если вы пытаетесь отписаться от делегата, у которого не подписан , вы получите ту же цепочку, что и у вас.
- Вы можете вручную пройтись по цепочке делегатов, чтобы увидеть, присутствует ли тот делегат, от которого вы хотите отказаться. Это можно сделать с помощью обычных методов Linq, таких как
.Contains
для простоты.
Первый случай может выглядеть как код ниже. Это создаст новую цепочку делегатов во временной переменной с делегатом, которого вы хотите удалить, удалить, а затем сравнить временную цепочку с существующей цепочкой. Если они одинаковы, делегат не присутствовал.
private EventHandler _Changed;
public event EventHandler Changed
{
add
{
_Changed += value;
}
remove
{
EventHandler temp = _Changed - value;
if (_Changed == null || temp == _Changed)
throw new InvalidOperationException(
"Delegate is not subscribed, cannot unsubscribe");
_Changed = temp;
}
}
Второй, как и код ниже, просто увидит, присутствует ли делегат, от которого вы хотите отказаться от подписки, в цепочке делегатов.
private EventHandler _Changed;
public event EventHandler Changed
{
add
{
_Changed += value;
}
remove
{
if (_Changed == null || !_Changed.GetInvocationList().Contains(value))
throw new InvalidOperationException(
"Delegate is not subscribed, cannot unsubscribe");
_Changed -= value;
}
}
Обратите внимание, что вы можете, если хотите, использовать подобный код для обработки случая, когда делегат добавляется дважды.