C# Generics and anonymous methods

Posted on 14th of November 2008

I’ve never been much of a C# maven or anything, but I’ve really fallen in love with this construct in the language. One thing which I guess almost anyone does alot of is building a string, from a list of business objects. Let’s say you have a list of GUIDs, and you either want to display them, or build an SQL string from them for use in a query.

List<Guid> gs;
string s;

foreach (Guid g in gs) {
    s += "Id='" + g.ToString() + "' OR ";
}

if (result.Length > 0) {
    s = s.Substring(0, s.Length-3);
}

That’s some good ole fashioned string fucking, and since I’ve come over from HTML/JavaScript/(Classic) ASP/PHP, that’s bussiness as usual by all standards. But I’ve never liked several aspects of it.

  • Since you’re appending to the string always, you need to take the last bit off, or the string turns malformed. That’s what the if construct does. It can sometimes be hard to connect a large foreach/for block with a succedding if block.
  • Contains magic numbers, in this case, 3. Can be avoided of course, if the bit that you’re appending is saved as a variable, and then you take the length of it. But that’s just more work.

Another approach, using generics and anonymous methods is the following

s = string.Join(" OR ",
        gs.ConvertAll(
            new Converter<Guid, string>(
                delegate(Guid g) {
                    return string.Format("Id='{0}'", g.ToString());
                }
            )
        ).ToArray()
    );

or, if you’re running C# 3.0 (my work is still using 2.0), you can do away with most of the syntax for the delegate construction.

s = string.Join(" OR ",
        gs.ConvertAll(
            new Converter<Guid, string>(
                g => string.Format("Id='{0}'", g.ToString())
            )
        ).ToArray()
    );

Which is a radical departure from the for loops of yore. Probably debatable if it’s an improvement in actual performance (string.Format is faster then old string concatenation, but you could use string.Format with the first approach too of course). It’s a much more functional approach, with no side-effects. But in terms of what is pleasing to the eye, I have no doubts, even if it’s spanning more lines, it just feels more right. You never end up over doing it, so there’s never any string to remove. The act of creating the strings you need, and then joining them is also seperated, which feels more right.

The downside is that it does become harder to debug. If you have a line like for instance

bool b = SomeMethod(GetSomeValue(param1, param2), param3);

Using either a normal debugger it’s not easy to break on the method call to GetSomeValue. The same would be the case with the list comprehension at work here. With no assigned value, it’s a little harder for the debugging. But given the simplicity, it usually proves to be a non-issue for myself.

Tags: , , ,

2 Responses to “C# Generics and anonymous methods”

  1. Jason Bunting Says:

    Your last example there can be shorted even further to this:

    s = string.Join(” OR “,
    gs.ConvertAll(
    g => string.Format(“Id=’{0}’”, g)
    ).ToArray()
    );

    The part in yours where you do the “new Converter” is inferred by the compiler, so it is really unnecessary. Also, you don’t have to explicitly call ToString() on g, since string.Format will do that internally regardless.

  2. Oleg Kosenkov Says:

    Surprisingly, nothing was sad about the StringBuilder class which may handle the string concatenations in a more optimal way. I have not looked under the hood of the framework but i hope the suggested functional lambda version does it optimally.

Leave a Reply