Tuesday, June 11, 2013

Function returning function in C#

I found the JavaScript library FChain on GitHub.

FChain is a library that can be used as a base to construct slideshows, presentations , image galleries or just used to run a predetermined number of functions in order. At it's core it is simply an array-like object of functions, which can be traversed through or automatically executed based on a timer.

What I like is the API. Here is the code sample from GitHub.
var setColor = function(color) {

    return function() {

        document.body.style.backgroundColor = color;
        console.log(color);
    }
}

// setup a chain with 3 functions
var fchain = FChain(setColor('red'), setColor('green'), setColor('blue'));

fchain.next(); //logs: 'red'
fchain.next().next(); //logs: 'green', 'blue'

The ability to pass a list of functions as parameter to be called at a later date is an interesting concept to build API. In the sample it is not yes Function Composition as we do not feed the returned value of one function as a parameter of another. I guess it some kind of chaining.

The question is how do write such an API in C#? Since C# has generic delegate and closure, this should be possible.

Here is my version
 
static Action SetColor(string color) {

    return new Action ( () => { Console.WriteLine("Color:{0}", color); } );
}

static void Main(string[] args) {

    var fChain = ChainClass.FChain(SetColor("Red"), SetColor("Green"), SetColor("Blue"));

    fChain.Next(); // Log Red
    fChain.Next().Next(); // Log Green, Blue
}
The C# complete source
class ChainClass {

    private List _functions;
    private int _index;

    public ChainClass(List functions) {
        this._functions = functions;
        this._index = 0;
    }
    public static ChainClass FChain(params Action [] functions) {
        return new ChainClass(functions.ToList());
    }
    public ChainClass Next() {
        this._functions[this._index]();
        this._index++;
        return this;
    }
    public void Clear() {
        this._functions.Clear();
    }
    public void SetNext(int index) {
        this._index = index;
    }
}        
static Action SetColor(string color) {

    return new Action ( () => { Console.WriteLine("Color:{0}", color); } );
}
static void Main(string[] args) {
 
    var fChain = ChainClass.FChain(SetColor("Red"), SetColor("Green"), SetColor("Blue"));

    fChain.Next(); // Log Red
    fChain.Next().Next(); // Log Green, Blue
}

No comments:

Post a Comment