Конечно, можно достичь того, что вы хотите сделать, но это не соответствует соглашению - я призываю вас найти другое решение, которое не включает события.
Как объяснил Джон Скит , публичные события являются подобными свойствам оболочками вокруг многоадресного делегата.
Вы можете думать о стандартной реализации события как о списке функций, которые будут вызываться, когда что-то происходит.
// From the above link:
// the exposed event
public event EventHandler MyEvent
// multicast delegate field
private EventHandler _myEvent;
// property-like add & remove handlers
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
... когда разработчик видит такое событие, он ожидает, что сможет подписаться на него без проблем, поскольку событие в основном говорит, что «любое количество типов может зарегистрироваться для получения этого уведомления о событии».
Похоже, вы хотите позволить кому-то установить реализацию, которая получает список окон. То, что я предложил бы сделать, это позволить людям вручную передать делегата, а затем сохранить единственный делегат экземпляр. Укажите, что есть только один способ установить его; если это вообще возможно, я бы порекомендовал использовать инъекцию в конструктор, поскольку это устраняет всю неоднозначность - вы можете установить экземпляр делегата только один раз при создании, тогда он больше не может быть изменен с помощью публичного API (так что класс B не может перекрыть уже установленный делегат по классу А).
* 1016 Е.Г. *
public class CallsDelegateToDoSomething
{
private Func<List<IBaseWindow>> m_windowLister;
public CallsDelegateToDoSomething(Func<List<IBaseWindow>> windowFunc)
{
m_windowLister = windowFunc;
}
public List<IBaseWindow> GetWindowList()
{
if (windowLister == null)
{
return new List<IBaseWindow>();
}
return m_windowLister();
}
}
Если ваш дизайн не допускает этого, просто создайте вместо него методы SetWindowLister(Func<List<IBaseWindow>> windowLister)
и ClearWindowLister()
.