Permalink

1

Don’t use Tuples use the ExpandoObject

Tuples came in .net 4 to store a sequence of elements. One of their intended uses is to return multiple values from a method without the need for out parameters. For example:

static void Main(string[] args)
{
    var address = GetAddressTuple();
    Console.WriteLine(address.Item1);
    Console.WriteLine(address.Item2);
    Console.WriteLine(address.Item3);
}

static Tuple<string, string, string> GetAddressTuple()
{
    return Tuple.Create("16", "Made Up Street", "XX5 5XX");
}

The problem is their just not very descriptive. When your reading code Item1, Item2 and Item3 properties don’t really tell you whats going on. In the example above they store the first line of the address, street and postcode, but you can’t tell that from just looking.

A better idea is to use the ExpandoObject. This is a dynamic object that allows you to add as many parameters to it as you like. Its better to use this to return multiple values as its more descriptive:

static void Main(string[] args)
{
    var address = GetAddressDynamic();
    Console.WriteLine(address.FirstLine);
    Console.WriteLine(address.SecondLine);
    Console.WriteLine(address.Postcode);
}

static dynamic GetAddressDynamic()
{
    dynamic address = new ExpandoObject();
    address.FirstLine = "16";
    address.SecondLine = "Made Up Street";
    address.Postcode = "XX5 5XX";
    return address;
}

Big problem with this though is that because an ExpandoObject is dynamic there is no intellisense. But still, in my opnion its easier to infer whats going on.

Also, another note. Tuples are read only after they have been created. This can also be another downside.

Permalink

0

Firefighting Development

And by this I mean reacting to customers needs instantly instead of adding them into the development plan. A lot of companies seem to fall in this trap and its understandable, the sooner you do something for a customer the sooner you can get paid. And when your starting up its pretty much essential to keep yourself afloat.

This kind of practice seems to go hand in hand with other pet hate. Doing EVERYTHING the customers asks for. Again this is tempting as it equals more money.

It is a problem though. You shouldn’t just develop everything your customers asks for. Because if you do you’ll find your self with one hell of a bespoke piece of software, and thats not a good thing. Its almost impossible to keep the code base clean if you’ve got switches all over the shop saying.

If Customer A then do this and that.

Your software will be a mangle of functionality thats only useful to one customer. You may think that the work your doing for one customer is going to be useful for another, and it may be, but chances are if you’re turning things around quickly you wont have chance to look at this properly.

It may seem completely counter intuative, but if you slow down your development and stop developing everything your customer asks for, you will end up with a better piece of software that will be easier to use. And because its easy to use chances are you’ll be able to sell it to more users and therefore make the money you would have otherwise got from developing everything.

Not doing everything the customer wants means you’ll have more time to spend on making sure your current functionality is as good as it can be and thats better in the long run. Its better solve 90% of the problem well than 100% of it poorly.

Permalink

0

Caching the Description Attribute on Enums

A while back I posted about the speed differences regarding getting descriptions from enums using two different methods. By reflecting a description attribute or using a switch statement. Now although using the description attribute is the cleaner of the two implementations it was also the slowest.

Talking to a friend about this he suggested I use caching on the description attribute to speed it up. And see what the difference was then.

So going back to my previous example. the time to get the description from 1,000,00 enums was:

Using the switch statement, 32ms
Using the description field, 16710ms

Now if I was to change the method for reflecting the description attribute to include caching. And by caching I mean, once I’ve reflected the enum first time round store it in an IDictionary so that I can pull it from there next time I need it, instead of having to reflect it again.

public static string ToDescriptionWithCaching(this Enum value)
{
    if (_enumDescriptionCache.ContainsKey(value) == false)
    {
        var description = (from m in value.GetType().GetMember(value.ToString())
                           let attr = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault()
                           select attr == null ? value.ToString() : attr.Description).FirstOrDefault();

        _enumDescriptionCache.Add(value, description);
    }
    return _enumDescriptionCache[value];
}

Now this small change to the code vastly improved the speed of the lookups. Now, getting the description on 1,000,000 enums takes approximately 578ms. That’s an improvement of 16 seconds!!

Permalink

1

Should you use the Description Attribute on an Enum?

Enumerations are great, they allow you to have property or variable that can only be set as a specific value. However they are very limited in what they can do.

Say for example you have a Document class that has a DocumentType enum property

public enum DocumentType
{
    ExcelDocument = 1,
    PdfDocument = 2
}

Then you want to output it to a web page or similar as text? Well you can’t. The ToString() method will just output the name of the Enum value, “ExcelDocument”. Not very readable.

Now there has been various solution suggested on how to solve this problem. It seems that the most popular method is to use the Description attribute on each of the enum values and write a little extension method to get hold of it. For example:

public enum DocumentType
{
    [Description("Excel Document")]
    ExcelDocument = 1,

    [Description("Pdf Document")]
    PdfDocument = 2
}

public static string ToDescription(this Enum value)
{
    return (from m in value.GetType().GetMember(value.ToString())
        let attr = (DescriptionAttribute)m.GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault()
	select attr == null ? value.ToString() : attr.Description).FirstOrDefault();
}

Its a nice tidy solution as it can be used on any enum, which is great for usability. However it turns out its very slow to execute in comparison to the more traditional solution of using a switch statement.

public static string ToDescription(this DocumentType documentType)
{
    switch (documentType)
    {
 	case FileType.ExcelDocument:
            return "Excel Document";
	case FileType.PdfDocument:
	    return "Pdf Document";
	default:
	    return "";
    }
}

Now although this method is bit more clunky and requires you to have a seperate method for each of your enums if speed is an issue and you’re executing this method a lot you should really go with the switch.

To give a comparison of speed I wrote a small app that 1,000,000 enums and then ran ToDescription() on each of them, the difference was large.

Using the switch statement took 32ms
Using the description field took 16710ms

Thats over 500 times as slow!!!