This is my personal blog. The views expressed on these pages are mine alone and not those of my employer.

Thursday, 30 August 2012

LINQ or readability?

We all know that cyclomatic complexity is directly correlated to bugs in your code and a great way to remedy this is by reducing the lines of code you write.

I recently stumbled across this article by Scott Hansleman which considered a number of scenarios where LINQ has the ability to improve our collective code-bases, through reducing lines.

To take an extract from his blog:
I visit a lot of customers and look at a lot of code. I also worked with a number of large production code bases in my previous jobs and I see a lot of ifs, fors and switches. I see loops inside of loops with ifs inside them, all doing various transformations of data from one form to another....I'd much rather write these one line operations than the loop and if above...(which are) simpler, terser, and less error prone than loops of loops.
However, like Scott points out, it is equally important to emphasise you should not cloud the water in an attempt to condense lines.  Readability is also king.

Here is an example that ReSharper recently suggested be condensed.

Code with a foreach loop:
decimal? total = 0;

foreach (var halfHour in halfHours)
{

    total += Calculate(data, halfHour.DateAndTime.Date, new
 List<string> {halfHour.HalfHourNumber});

}

return total;

Code using LINQ:
return halfHours.Aggregate<HalfHour, decimal?>(0, (current, halfHour) => 
current + Calculate(data, halfHour.DateAndTime.Date, new 
List<string> {halfHour.HalfHourNumber}));

This is certainly one for judgement, but I'd go with the most readable any day. So what do you think?


Update:

I've become aware that infact this article is relating to a lambda expression rather than LINQ itself (which can't be used interchangeably), and therefore the post isn't factually correct in that regard. I'll be describing in a future post what each of these mean and the differences between the two, as I hadn't been aware of the distinct difference myself. The core point of the post remains however.

Wednesday, 22 August 2012

The importance of code

Recently I've noticed that when people learn of my occupation 9 out of 10 times the first question out of their mouth is "so what languages can you write?" which is a question that troubles me somewhat.

The problem is the assumption that software development is simply a set of distinct languages that can be learned and mastered in the same way you would learn Spanish or French.  In reality the multitude of languages that exist are merely tools and nothing more, and the field of software development has (very) little to do with knowing languages.

A great example are the hoards of developers who would call themselves a C# developer but wouldn't touch VB with a bargepole.  Well here's a secret, the differences are purely syntactical, they use the same paradigm (object oriented) and the both compile to the same intermediate language so in reality they already "know" VB.

The real question we should be asking each other are "what technologies are you working on, and does it challenge any of my currently accepted norms?"

We must be really careful not to pigeon-hole ourselves into language-shaped boxes, but to understand that the languages we use at work are just the tip of the iceberg. Software development is a craft in the same way as other professions.

I'll leave you with this fitting analogy:
Code to a developer is the same as a pencil is to an engineer.

Monday, 6 August 2012

Virtual Method Call In contructor

I recently discovered the following warning from ReSharper:

So what exactly does Virtual member call in constructor actually mean, and why am I being warned about this?

Virtual members


In C# a virtual member is a method or property which is prepended with the modifier virtual, meaning that it may be overridden in a child class but unlike the abstract modifier it doesn't have to be.  Since a virtual member may be overridden many times, only the most derived type will be executed.

Constructors


Since only the most derived virtual member is executed this can lead to a unique problem in the scenario where the virtual member is contained within a constructor. To understand this consider the following two classes:

ClassA
class ClassA
    {
        public ClassA()
        {
            SplitTheWords();
        }

        public virtual void SplitTheWords()
        {
            //I've been overridden
        }
    }

ClassB
class ClassB : ClassA
    {
        private readonly String _output;

        public ClassB()
        {
            _output = "Constructor has occured";
        }

        public override void SplitTheWords()
        {
            String[] something = _output.Split(new[]{' '}); //Bang!
        }
    }

If I create an instance of ClassB, then the constructor of ClassA will be called and SplitTheWords() will be executed.  Now because SplitTheWords() is virtual, then only SplitTheWords() in ClassB will actually be executed (the most derived class) before the constructor of ClassB has been.  Which means we could be using an object in an unsuitable state.

Resharper recommends to make the virtual member in ClassA sealed, which means that it cannot be overridden and must be the most derived type, which entirely solves this problem.

I believe this is exactly the kind of thing which would get overlooked in your codebase, and just goes to show what a useful tool ReSharper actually is.  A more concise explanation of this situation is available in the ReSharper docs.

Note about comments below:

Due to a typo I made, an earlier version of the post didn't exhibit the behaviour described, and I very much thank those who took the time to point this out to me.  This have now been fixed, although I believe a deeper explanation as to the reasons behind this article is warranted:

[10.11] of the C# Specification tells us that object constructors run in order from the base class first, to the most inherited class last.  Whereas [10.6.3] of the specification tells us that it is the most derived implementation of a virtual member (in this case ClassB) which is executed at run-time.

Therefore when you call a virtual member in a constructor the following can happen because the most derived implementation of a virtual member was contained within an object whose constructor hadn't been executed yet: