Pages

Tuesday, April 27, 2010

C# Anonymous Methods

C# Anonymous Menthods


With C# 4.0 here and the new dynamic feature, that can be used in lambdas, many cool scenarios are possible, and the mis use of dynamic will be probably high.

But the main focus of this post will be anonymous types from C# 2.0 and 3.5 (I'm not in a mood to going all the way with 4.0 just right now), and what can be done with them. Normally when using objects and creating something we don't see the properties as this gets evaluated in runtime, but with anonymous types this is not the case, we can create an object and see it's properties, but such created object has an assembly scope, and its read only, so the uses are limited, but in cases like linq it's great, but if we would like to create such object for our internal uses and not invoke linq into it but for e.g lambdas or just methods we could do this:.

/// <summary>
/// Creates the specified anonymous type.
/// </summary>
/// <remarks>
/// It is worth noting that the anonymous type has read only
/// properties.
/// </remarks>
public T Create<T>(Func<T> func)
{
    return func();
}

and then use the method like so:

Anonymous a = new Anonymous();
var result = a.Create(() => new { name = "bartosz" });

Now when we use the result, we will get access to the 'name' property.

But like I said this is somewhat limited, so now lets incorporate generics and anonymous delegates.
Let's say that we have some delegate but want to decorate it, or change its functionality then we can use anonymous delegates.

/// <summary>
/// Creates the delegate with a logging functionality.
/// </summary>
public Func<bool,T> CreateLog<T>(Func<T> method)
{
    return delegate(bool b)
    {
        if (b)
        {
            Console.WriteLine("log");
        }
        return method();
    };
}

Now this may be not a good example, but I hope you get the point of what can be done. The more practical and classic thing that can be done with this is Currying.

/// <summary>
/// Curried function.
/// </summary>
public Func<int,int> Curry(int param)
{
    int acc = param;

    return delegate(int p)
    {
        acc += p;
        return acc;
    };
}

It's basically an addition function, that takes only one parameter (we could add params here for more), and returns a new delegate that accumulates the value of the original function and when invoked add the accumulated value to the current parameter.

Anonymous a = new Anonymous();
var curry = a.Curry(4)(2);

The result of this operation is 6.

There are other better application for it, like parameter reduction, but for now i'm not gonna go into that. Next up it's going to be probably something regarding lambdas and dynamic keyword.

No comments:

 
ranktrackr.net