Archive for the ‘.NET’ Category

NLog 2.0 Release Candidate is out!

It is my pleasure to announce that the Release Candidate (RC) of NLog 2.0 is now available for download. This is the last milestone before NLog 2.0 final release.

  • Binary downloads are available on CodePlex
  • Source code on GitHub
  • Full release notes can be found here.

Please download the release and report any problems you may find. Assuming no critical issues are found, NLog 2.0 will be released within a month from the RC release.

 

No Comments


Attaching LINQ expression trees to delegates

Inspired by discussion on Twitter today, I started exploring the possibility of attaching LINQ expression trees to compiled delegates. The idea is that you could pass around Func<T> instead of Expression<Func<T>> yet still be able to retrieve original expression tree used to compile the delegate. This makes some scenarios (testing, logging) much cleaner, because you don’t need to deal with expressions as much.

But how do you attach anything to a delegate and Func<T> in particular? Aren’t delegates essentially function pointers?

Well – in .NET each delegate holds information about both the target object instance and the method to invoke on it. This makes it possible to create a tiny wrapper object that would have a function which behaves like Func<T> but holds additional state. Let’s look at a simple wrapper for Func<T> which stores expression:

public class FuncWithExpression<TResult>
{
    private readonly Func<TResult> wrappedFunction;

    public FuncWithExpression(Expression<Func<TResult>> expression, Func<TResult> func)
    {
        this.Expression = expression;
        this.wrappedFunction = func;
    }

    public TResult Function()
    {
        return wrappedFunction();
    }

    public Expression<Func<TResult>> Expression { get; private set; }
}

Let us also define two of extensions methods: one which compiles Expression<Func<T>> and wraps the result with FuncWithExpression<T> wrapper and the other one which extracts the expression from Func<T>:

public static class ExtensionMethods
{
    public static Func<T> CompileAndWrap<T>(this Expression<Func<T>> expression)
    {
        Func<T> compiledExpression = expression.Compile();
        return new FuncWithExpression<T>(expression, compiledExpression).Function;
    }

    public static Expression<Func<T>> GetExpression<T>(this Func<T> func)
    {
        var exp = func.Target as FuncWithExpression<T>;
        if (exp != null)
        {
            return exp.Expression;
        }

        return null;
    }
}

That’s it! (Of course, in real life you would need to provide overloads for more Func<> types, since functions without arguments are not typically very useful). You can now write the code using just Func<T> and still be able to retrieve original expression tree used to compile the delegate:

class Program
{
    static void PrintAndExecute(Func<int> func)
    {
        Expression originalExpression = func.GetExpression();
        if (originalExpression != null)
        {
            Console.WriteLine("expression: {0}", originalExpression);
        }

        Console.WriteLine("result: {0}", func());
    }

    static void Main(string[] args)
    {
        var body = Expression.Add(Expression.Constant(3), Expression.Constant(9));
        Expression<Func<int>> expr = Expression.Lambda<Func<int>>(body);
        Func<int> compiledExpression = expr.CompileAndWrap();

        PrintAndExecute(compiledExpression);
    }
}

This will print:

image

No Comments



SetPageWidth