IL fun fact: not is not ! 4
Picture yourself working on crafting a specific piece of CIL.
You need to write the compiled equivalent of:
bool b = ...; bool n = !b;
It would be tempting to write:
ldloc b not stloc n
Except that it would not always work. not doesn’t negate booleans, it computes the bitwise complement of the value on the stack. It’s also not to be confused with the neg opcode, which negates a value, as in a multiplication by -1.
The usual pattern to negate a boolean is:
ldloc b ldc.i4.0 ceq stloc n
But that’s not really fun, is it?
Actual fun fact: there’s a misused “not” in the ECMA 335 in the example of the section 14.5 of the partition II.
Fun fact: C# methods whose bodies span over multiple source files 4
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
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
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.