Coding Efficiency vs Readability in C#

c

I am fairly new to c# and trying to learn best practices. I've been faced with many situations over the last week in which I need to make a choice between longer+simpler code, or shorter code that combines several actions into a single statement. What are some standards you veteran coders use when trying to write clear, concise code? Here is an example of code I'm writing with two options. Which is preferable?

A)

    if (ncPointType.StartsWith("A"))//analog points
    {
        string[] precisionString = Regex.Split(unitsParam.Last(), ", ");
        precision = int.Parse(precisionString[1]);
    }
    else
    {
        precision = null;
    }

B)

    if (ncPointType.StartsWith("A"))//analog points
        precision = int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]);
    else
        precision = null;

C)

    precision = ncPointType.StartsWith("A") == true ? 
            int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]) : 
            null;

Best Answer

It's just like writing in English. Concise is rarely a bad thing, as long as the reader can see all the information they need to understand the intent.

The reason option C isn't perfectly readable is not because it's TOO concise, it's because it's not concise enough. Look at it again:

precision = ncPointType.StartsWith("A") == true ? 
            int.Parse(Regex.Split(unitsParam.Last(), ", ")[1]) : 
            null;

What if it said this?

precision = ncPointType.StartsWith("A") ? SecondToken(unitsParam.Last()) : null

That seems pretty readable to me. It's very clear that if ncPointType starts with an A, we'll set the precision to the second token in the last parameter of unitsParam. Otherwise we'll set it to null.

The details of tokenization is irrelevant to the person reading this line of code. But if they want to know, they can look at the method, which will say.

public int SecondToken(string param)
{
    return int.Parse(GetTokens(param)[1]);
}

Makes sense. Very clear. And then ...

public string[] GetTokens(string param)
{
    return Regex.Split(param, ", ");
}

Now you're going to say that this is a lot more words than any of your options. And it is. But think of each method as part of a glossary of terms. You're creating a language as you go.

Not doing this is like trying to write a story about your pets, having removed the words dog and cat from the dictionary.

There are a lot of words in the definition of dog; even more in the dictionary as a whole. But not having that definition for dog means you have to say "domesticated carnivorous mammal" instead and your story becomes less readable.

That said, as I alluded at the beginning, there is a point at which you lose information. For example:

precision = ncPointType.IsOk() ? GetIt() : Dont();

This is a step too far. To beat the last piece of usefulness out of an analogy: It's like writing a story about your pets, referring to them always as "it".

Related Topic