Thursday, January 29, 2009

Poor man's string interpolation in C#

String interpolation is a nice feature in some languages like PHP, Ruby, Perl, Boo and Nemerle that makes string formatting very easy. Its absence in C# causes language envy, feature requests and hacks like these and the one presented here.

The way I see it, string interpolation is just applying a string template. So we could use a light, simple templating engine like NVelocity. That covers the templating problem.

The other problem is the gathering of the values to be injected in the template. This is pretty much unsolvable in C# because the compiler doesn't store local variable names in the assembly. Of the .NET languages I mentioned before, Boo and Nemerle, Boo just has this feature built into the compiler. If you write this in Boo:

product = "keyboard"
price = 123
text = "The ${product} costs ${price}"
print text

It compiles to this:

private static void Main(string[] argv) {
    string product = "keyboard";
    int price = 0x7b;
    Console.WriteLine(new StringBuilder("The ").Append(product).Append(" costs ").Append(price).ToString());
}

Nemerle solves string interpolation by using its strong macro capabilities.

C# has none of these features, so one way or another we have to manually define the parameters. So it's just a matter of finding the easiest way to define named parameters. How about this one?

[Test]
public void Formatting() {
    var product = "keyboard";
    var price = 123.55m;
    var result = "The $product costs $price.ToString('C')".Fill(new { product, price });
    Assert.AreEqual("The keyboard costs $123.55", result);
}

I guess that's about as close as I can get. It's not the same as having it supported by the language, but it's certainly prettier that String.Format()...

Source code is here.

No comments: