The Anonymous Implementation pattern (as seen in the Reactive Extensions)

There’s a pattern used in the Reactive Extensions that I’m calling the Anonymous Implementation.

You can see it in use on IObservable’s one method

IDisposable Subscribe(IObserver<T> observer);

Given an Observable which you want to subscribe to, the brute force, naive (or pedantic) approach would be to create a new class implementing IObserver<T> and then subscribe it.

public class BasicConsoleWriteLineObserver<T>: IObserver<T>
{
    public void OnNext(T value)
    {
        Console.WriteLine(value);
    }
    
    public void OnError(Exception ex) 
    {
        throw ex;
    }
    public void OnCompleted() { }
}

IObservable<int> stream = ...;
stream.Subscribe(new BasicConsoleWriteLineObserver<int>());

But a simpler method, one that dispenses of all the ceremony of creating a new Type is to use one of the Observer factory methods, like so:

IObserver<int> basicCWLobserver = Observer.Create((int value) => Console.WriteLine(value));
stream.Subscribe(basicCWLobserver);

Observer.Create (and it’s 4 overloads) will create an anonymous implementation of the interface needed. Of course you can skip a step or two and use the extension methods on IObservable to get even shorter versions of the same:

stream.Subscribe(Console.WriteLine);

This approach is great, for all but the most complex implementations, there’s no need to ever implement IObserver<T>.  And as they say, less code is better code.

 

There are a number of other interfaces that I wish used this approach. IValueConverter, and IComparer<T> come to mind first.

3 Comments

  • i think the newer method overloads now take a Comparison delegate so that you don't have to implement IComparer. Not sure about IValueConverter though.

  • Comparison&lt;T&gt; - nice to know about. Looks like others have the need for converting to IComparer
    dpatrickcaldwell.blogspot.com/.../converting-comparison-to-icomparer.html

  • Does that make an anonymous (or any) type constructor the dual of Observable.Create? One creates an instance of a type - data, the other an instance of a function, a computation?

Comments have been disabled for this content.