2016-04-21 1 views
-2

У меня есть ситуация, когда несколько классов регистрируют интерес к другому классу для наблюдения за значением определенного свойства. Это делается с помощью делегатов, как так:C# проверить, имеет ли делектор/func действительный приемник

public delegate void ObservingHandler (object value); 

Dictionary<ObservingHandler, ObservationInfo> _handlers = new Dictionary<ObservationHandler, ObservationInfo>(); 

public void register(ObservingHandler handler) { 

    // Observation info is created here and is just a struct 
    _handlers.Add(handler, info); 
} 

Это прекрасно работает, и это действительно полезно, но в настоящее время, когда зарегистрированный объект отпущен, он должен сообщить соответствующий класс, что он больше не хочет получать уведомления. В противном случае я получаю NULL ссылочные исключения.

В настоящее время это означает, что я не могу использовать лямбда-выражения, потому что обработчик наблюдения является ключом в словаре (и поэтому должен быть тем же самым экземпляром, когда дело доходит до его удаления).

Что бы я хотел сделать, это проверить, что каждый ObservationHandler имеет действительный и созданный экземпляр класса позади него до его вызова. Таким образом, ответственность отнимает класс слушателей.

Есть ли способ в Func или delegate, чтобы проверить приемник функции живой и хорошо?

EDIT:

Полный исходный код приходит от моего проекта под названием SFCore on GitHub.

+2

«В противном случае я получаю эксплименты» - какие исключения? Не совсем понятно, что вы имеете в виду - пожалуйста, покажите [mcve], демонстрирующую проблему. –

+0

«ObservingHandler» - это ссылка на метод в классе наблюдения. Если класс наблюдения освобожден, «ObservingHandler» содержит ссылку на метод в нулевом классе. Я считаю, что исключение - это исключение с нулевой ссылкой. Поэтому прямо сейчас у меня должен быть класс регистрации перед деблокированием, но я хотел бы узнать, есть ли у ObservingHandler встроенный наблюдатель. –

+0

Вместо того, чтобы «верить», что исключение является исключением NullReferenceException, почему бы вам не показать нам пример? Я ожидал бы ссылки ObservingHandler, чтобы сохранить цель живой автоматически - здесь нет «выпуска». В принципе, пока вы не сможете воспроизвести проблему в сжатой форме, вам будет очень сложно помочь. –

ответ

1

Я бы пошел с моделью событий .NET и оставил ответственность за слушателя, ведь если ваш тест не по какой-либо причине, ваш получатель больше не будет уведомлен.

Что бы я сделал, это, уведомив слушателей, уловить любые исключения, которые могут возникнуть.

Если возникло исключение из-за того, что класс больше не существует (не может быть более конкретным, вы не указали точное имя исключения), вы либо игнорируете его (считая, что это только одноразовый ошибка) ИЛИ удалить его из словаря.

Снова это то, что я сделал бы, для этого есть, конечно, другие способы.

+0

Спасибо, это хорошая идея. Есть ли способ, который вы знаете, чтобы сообщить перед тем, как уведомить слушателя, если слушатель фактически существует? Я предполагаю, что «событие» делает это, но я понятия не имею, как это сделать. –

0

Observer pattern in C# достигается за счет событий. Использование ключевого слова event будет основано на вашем описании.

Вам не нужно отслеживать обратные вызовы на этом уровне хранения Словаря, как у вас в вашем примере. Все, что вы делаете в своем разговоре, - это огонь.

+0

Но вам все же нужно проверить при запуске события, которое у вас есть у наблюдателей, если вы этого не сделаете, у вас будет хороший «NullReferenceException» – Sidewinder94

+1

нет, если у вас всегда есть хотя бы один слушатель: event EventHandler MyEvent = (s, e) => {}; –

+0

Ну, я привык проверять нуль в этих случаях :) Но это еще один способ взглянуть на это. – Sidewinder94

Смежные вопросы