как я могу преобразовать это, чтобы использовать Rx, а не события стиля .NET?

1

В соответствии с более ранним вопросом, я сказал пользователю, что я не должен выставлять API-интерфейс.NET Event-style, если только не будет принудительно:

Если вы не будете вынуждены сделать это, не делайте API с использованием событий стиля С#.

В этом случае, как мне реализовать "событие", когда модель будет уведомлять наблюдателей о том, что она каким-то образом изменилась? Событие ожидается только один раз. Скажем, например, что моя модель представляет собой блок Minecraft, и я вызываю метод Destroy() на этой модели. Метод Destroy() должен передавать наблюдателям, что эта модель намеревается уничтожить. Например, наблюдатели будут контроллером, который затем отправит уведомление BlockDestroyed в представление (я считаю, что контроллер может быть ненужным уровнем косвенности, но гораздо проще сделать модель → контроллер → просмотр, а не модель (наблюдаемая) - > view (observer)).

Вот мой код, который я бы хотел изменить в стиле Rx - помните, что Destroyed будет вызываться только один раз за блок - и могут быть другие события, такие как Damaged, Activated и TextureChanged.

public class Block
{
    public Block()
    {
    }

    /// <summary>
    /// Destroy the block.
    /// </summary>
    public void Destroy()
    {
        var msg = new BlockDestroyedMessage();
        if (Destroyed != null)
            Destroyed(this, msg);
    }

    public event EventHandler<BlockDestroyedMessage> Destroyed;
}

Также обратите внимание, что я вижу документацию по сети, которая в основном вы

  • Следует избегать ISubject<T> поскольку он поощряет нарушение SRP (с которым я согласен)
  • Не реализуйте IObservable<T> (потому что существует так много заводских методов для создания наблюдаемых)
Теги:
system.reactive

1 ответ

1
Лучший ответ

Я бы сделал это:

public class Block
{
    public void Destroy()
    {
        if (_destroyed != null)
        {
            var msg = new BlockDestroyedMessage();
            _destroyed.OnNext(msg);
            _destroyed.OnCompleted();
            _destroyed = null;
        }
    }
    private Subject<BlockDestroyedMessage> _destroyed
        = new Subject<BlockDestroyedMessage>();

    public readonly IObservable<BlockDestroyedMessage> Destroyed
        = _destroyed.AsObservable();
}
  • 0
    По сути, это то, что я бы предложил, хотя я бы выставил IObservable как свойство только для чтения, а не как изменяемое поле.
  • 0
    @MikeStrobel - Да, хорошая мысль.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню