Dan
Dan

Reputation: 10548

how can I convert this to use Rx rather than .NET style events?

As per an earlier question, I was told by a user that I should not expose a .NET Event-style API unless absolutely forced to:

If you're not positively forced to do so, do not make an API using C# style events.

In this case, how should I implement an "event" whereby a model will notify any observers that it has changed in some way? The event is only expected to be called once. Let's say for example that my model is a Minecraft Block, and I invoke the method Destroy() on this model. The Destroy() method should broadcast to it's observers that that model intends to be destroyed. Example observers would be a controller that would then send a BlockDestroyed notification to the view (I appreciate the controller could be an unnecessary level of indirection however it is a lot easier to do model -> controller -> view rather than model (observable) -> view (observer)).

Here is my code that I would intend to alter to an Rx style - remember, Destroyed would only be invoked once per block - and there could be other events, such as Damaged, Activated, and 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;
}

Also note that I am seeing documentation over the web that basically you

Upvotes: 1

Views: 123

Answers (1)

Enigmativity
Enigmativity

Reputation: 117175

I would do this:

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();
}

Upvotes: 1

Related Questions