简体   繁体   中英

How to link IObservable and IObserver in C#?

I've been studying Observer parttern since this morning, but can't seem to figure out how to implement it with the built-in interfaces. I already looked at some examples but couldn't find any simple example yet.

Here's my code so far, inspired by the Microsoft Documentation :

class ObservableClass : IObservable<bool>, IDisposable
{
    public bool observableBool;
    public List<IObserver<bool>> observers;

    public ObservableClass()
    {
        this.observableBool = false;
        this.observers = new List<IObserver<bool>>();
    }
    public IDisposable Subscribe(IObserver<bool> observer)
    {
        if (!observers.Contains(observer))
        {
            AddObserver(observer);
        }
        return this;
    }
    public void Dispose()
    {
        Console.WriteLine("Disposing...");
    }

    public void AddObserver(IObserver<bool> obs)
    {
        this.observers.Add(obs);
    }

    public void RemoveObserver(IObserver<bool> obs)
    {
        this.observers.Remove(obs);
    }

    public void SwapBool()
    {
        observableBool = !observableBool;
    }

}

the observable class contains an observableBool field. I want to notify the Observer when that field changes value.

Here's my Observer :

class ObserverClass : IObserver<bool>
{
    public IDisposable observable;
    public void OnCompleted()
    {
        Console.WriteLine("Completed");
    }

    public void OnError(Exception error)
    {
        Console.WriteLine("error");
    }

    public void OnNext(bool value)
    {
        Console.WriteLine("Next");
    }
    public virtual void Subscribe(IObservable<bool> obs)
    {
        if (obs != null)
            observable = obs.Subscribe(this);
    }

    public void stopObserve()
    {
        observable.Dispose();
    }
}

And finally my Program :

static void Main(string[] args)
    {
        ObservableClass observable = new ObservableClass();
        ObserverClass observer = new ObserverClass();
        observer.Subscribe(observable);
        Console.WriteLine("subscribed observer");
        observable.SwapBool();
        Console.WriteLine("performed swapBool");
    }

Expected output :

subscribed observer
Completed //Returned by ObserverClass.OnComplete()
performed swapBool

How to make this work ? How to call on OnComplete and the other methods of ObserverClass everytime observableBool changes ?

I know there are other ways to do that, but my goal is to be able to use IObserver and IObservable.

You iterate over your set of observables to notify them:

public void SwapBool()
{
    observableBool = !observableBool;
    foreach (observable in observers)
    {
        observable.OnNext(observableBool);
    }
}

You are meant to call OnNext when there is a new value. OnComplete is used to notify that there will be no more values.


I just noticed your observable is IDisposable ...

First of all, disposing the result of Subscribe should unsubscribe that observer. Not dispose the observable.

In fact, I would expect that disposing the observable means that it will no longer be sending values (calls OnComplete on everybody and releases the list of observers).

Other concerns include:

  • You probably want a set type so you can add and remove observables more efficiently.
  • List is not thread-safe.
  • Why are you exposing your fields?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM