Fun fact: C# methods whose bodies span over multiple source files 4

Posted by Jb Evain Thu, 19 Jan 2012 21:00:00 GMT

While working on Mono.Cecil (your lovely library to analyze and manipulate .net binaries that is used by legions), one thing that struck me as odd for a while, was the fact that a method could have debug symbols for instructions that are defined in multiple files.

Cecil has this type, Instruction. When you’re analyzing a module with debug information (think .pdb or .mdb files), an Instruction may have its SequencePoint property set. A sequence point is nothing but the location of the code in a file that relates to the instruction.

What got me wondering, is that the APIs to retrieve those sequence points make it so that a method can have sequence points in different documents. So be it, this is how I ended up representing it in Cecil, but it’s only recently that I stumbled upon a case where indeed, a C# method had instructions defined in multiple files:

Foo.Bar.cs:
public partial class Foo {
    private List<Bar> _bars = new List<Bar>();
}

Foo.Baz.cs:

public partial class Foo {
    private Baz _baz;

    public Foo (Baz baz)
    {
        _baz = baz;
    }
}

Do you see what’s going on here?

The constructor of Foo is defined in Foo.Baz.cs, but there’s a field initializer in Foo.Bar.cs that is going to be compiled inside Foo’s constructor. When you debug the constructor, you’ll effectively end up jumping between the two files. Crazy right?

Can you think of another case where a C# (or VB.NET for that matters) method would have instructions defined in different files?

Constraining generic constraints 1

Posted by Jb Evain Fri, 13 Jan 2012 13:30:00 GMT

This is the last part of an update about Mono.Linq.Expressions, a tiny helper library to complement the System.Linq.Expressions namespace for .net 4 and Mono.

And it's not really about Mono.Linq.Expressions itself. If you're interested about it though, you can read the part about fluently creating expression trees, and the other one about combining lambda expressions together.

Proper generic constraints


Have a look at the signature of the factory method Expression.Lambda:

public static Expression<TDelegate> Lambda<TDelegate> (
    Expression body,
    params ParameterExpression [] parameters) {}

And at the signature of Expression<T>:

public sealed class Expression<T> : LambdaExpression {}

Given the post title, and the <h3> a few lines up there, it's obvious where I'm going: those generic parameters have no constraint. A C# compiler will happily compile:

class Potato {}

Expression<Potato> e = Expression.Lambda<Potato> (
    Expression.Constant (new Potato ()));

Of course this won't get you far, but it sure is a heart breaker that because of a little language oddity, you delay to until runtime the problem resolution: this code will throw, Potato sure isn't a Delegate type, and Expression.Lambda, the only way to create an Expression<T> is making sure of that.

So much for type safety, generics!

Another famous issue is the following. Again, for the compiler, it's perfectly legit to write:

int i;
if (!Enum.TryParse ("42", out i))
    Console.WriteLine ("This is so unfair!");

And why is that? Because of the signature of Enum.TryParse:

public static bool TryParse<TEnum> (string value, out TEnum result) where TEnum : struct {}

To sum the issue up, C# doesn't allow generic constraints on delegates and enums. And why am I rumbling about this? Because Mono.Linq.Expressions has this method:

public static Expression<T> Combine<T> (
    this Expression<T> self,
    Func<Expression, Expression> combinator)

And if Expression<T> is not constrained on Delegate, then I sure as hell won't let this stand in my own public API! Which is why the actual signature of the Combine method is:

public static Expression<T> Combine<[DelegateConstraint] T> (
    this Expression<T> self,
    Func<Expression, Expression> combinator) where T : class

And all of this was just a perfect excuse to write a little Mono.Cecil based utility tool, appropriately named patch-constraints, that is used as a post-compile step to fixup the Delegate and Enum constraints of any generic parameter decorated respectively with a DelegateConstraintAttribute or EnumConstraintAttribute, turning them into actual constraints to delegates and enums, which, funnily enough, the C# compiler is more than happy to honor.

Obviously I could have used the most famous Jon Skeet's unconstrained-melody tool, but 2002 called and it wants its ildasm based, IL text parser back.

Mono.Linq.Expressions update 2

Posted by Jb Evain Thu, 12 Jan 2012 11:25:00 GMT

This is the second part of an update about Mono.Linq.Expressions, a tiny helper library to complement the System.Linq.Expressions namespace for .net 4 and Mono.

The first part is about fluent creation of expression trees.

Combining expression trees together


I keep reading questions on StackOverflow about this. How to combine two lambda expression together? If we have:

Expression<Func<User, bool>> isUserOver18 = u => u.Age >= 18;
Expression<Func<User, bool>> isFemaleUser = u => u.Gender == Gender.Female;

If we want to combine this lambda expression with a “and” logical expression, the natural way would be to write:

Expression<Func<User, bool>> isFemaleUserOver18 = u =>
    isUserOver18(u) && isFemaleUser(u);

This works just fine if you compile the expression into a delegate to actually execute this code. But most of the time questions of StackOverflow are about using the resulting lambda expression to create a query for LINQ to a database provider, which will analyze the expression tree and create an according SQL request.

By combining expression trees this way, the LINQ provider may or may not be unable to turn the two invocations into actual SQL.

That's one of the reason I wrote about an updated PredicateBuilder. The obvious solution is to inline the two combined representation of lambda expressions into a new lambda expression tree.

The update of Mono.Linq.Expressions comes with a new type, CombineExtensions, which exposes extension methods that you can use to combine fully created (into lambda expressions) expression trees.

Using those, combining the two expression trees is as simple as:

Expression<Func<User, bool>> isFemaleUserOver18 = isUserOver18.Combine(
    isFemaleUser,
    (left, right) => left.AndAlso(right));

And indeed, if you print the code representation of this expression tree, you'll have both lambda bodies inlined into another one:

user => user.Age >= 18 && user.Gender == Gender.Female

Or if you want to negate the boolean expression:

Expression<Func<User, bool>> isNotFemaleUserOver18 = isFemaleUserOver18.Combine(
    e => e.Not());

The cool thing about those Combine extension methods is that they're completely generic, they don't work only on simple predicates. For instance, you can use those to chain constructions of mathematical expressions.

Mono.Linq.Expressions update 2

Posted by Jb Evain Wed, 11 Jan 2012 16:00:00 GMT

I just tagged the 1.2 version of Mono.Linq.Expressions, and pushed an updated nuget package.

Mono.Linq.Expressions is a utility library to complement the System.Linq.Expressions namespace, and works with .net 4.0 just as fine as it does with Mono. With a bit over 220 downloads of the nuget package, it's short of roughly 160,400 downloads to be the most downloaded nuget package : a stunning success to put it simply.

This post is the first of a short series to detail what's awesome and new in this version.

Extension methods for a fluent construction of expression trees.


Have you been using the expression tree API to build a representation of code at runtime ? If so you're familiar with the Expression class, and it's load of factory methods.

You're also familiar with this kind of code:

var user = Expression.Parameter(typeof (User), "user");

var isFemaleUserOver18 = Expression.Lambda<Func<User, bool>>(
    Expression.AndAlso(
        Expression.GreaterThanOrEqual(
            Expression.Property(user, "Age"),
            Expression.Constant(18)),
        Expression.Equal(
            Expression.Property(user, "Gender"),
            Expression.Constant(Gender.Female))), user);

If you take some time to parse this code, the intent is to create an expression tree similar to the one the compiler would emit if you were to write:

Expression<Func<User, bool>> isFemaleUserOver18 =
    user => user.Age >= 18 && user.Gender == Gender.Female;

Mono.Linq.Expressions 1.2 contains a code generated series of extension methods to simplify the manual construction of expression trees by fluently chaining the invocations. This allows you to write instead:

var user = typeof (User).Parameter("user");

var isFemaleUserOver18 = Expression.Lambda<Func<User, bool>>(
    user.Property("Age").GreaterThanOrEqual(18.Constant())
    .AndAlso(
        user.Property("Gender").Equal(Gender.Female.Constant())), user);

Not only is the code shorter, but it's also easier on the eyes, and easier to comprehend. Using this, almost the factory methods calls to the Expression class can be written fluently.

Older posts: 1 2 3 ... 37