C# 6.0 features that help reduce errors in your code

After starting to use C# 6.0 for Windows 10 apps, I found that some of the most useful features to me were ones that could help cut down minor errors in my code. A simple typo can sometimes be a real pain to diagnose and resolve. For me any feature that can help reduce the risk that lack of sleep and poor typing skills can sometimes throw into a project is great. In this post I want to just go through a few of the features that developers may have overlooked and how they can help cut down those annoying little errors.

String interpolation

Working with strings can often end up with simple bugs, often just at a UI level where spaces are lost or additional ones added. The most basic way of concatenating a string together in code often makes it difficult to read to a developer.

public string Addition(int x, int y)
{
    int result = x + y;
    return "Adding " + x + " and " + y + " equals " + result;
}

To get round this we can use string.Format which keeps the string part together, but then allows the developer to add an array of values to include in the string when it is called

public string Addition(int x, int y)
{
    return string.Format("Adding {0} and {1} equals {2}", x, y, x + y);
}

Although a better solution than the first one, it can still lead to basic errors and mistakes such as not entering the right number of values in the array and causing a NullReferenceException. You may think this is easy to avoid, but as developers, not only should we be coding defensively, but also thinking about those who will maintain the code after us. I’m sure most developers have seen the situation where changes over time have resulted in something like this:

public string Addition(int x, int y)
{
    return string.Format("Adding {1} and {2} equals {0}", x + y, y, x);
}

With C# 6.0 we can use string interpolation to include values in our string by starting the string with a $ character and then including expressions inside of braces:

public string Addition(int x, int y)
{
    return $"Adding {x} and {y} equals { x + y }";
}

nameof operator

The nameof operator returns the name of member/variable etc that it is called against as a string. Using this operator rather than a string allows this reference to be used by Visual Studio. A great example of how this can be used to reduce basic code errors is when using MVVM and calling RaisePropertyChanged.

This first example shows a standard call to RaisePropertyChanged taken from one of my Windows 8 apps.

private string currentLapTime;

public string CurrentLapTime
{
    get { return currentLapTime; }
    set
    {
        currentLapTime = value;
        RaisePropertyChanged("CurrentLapTime");
    }
}

The problem with this, which is one I have fallen foul of on more than one occasion, is that if you enter a typo in the string there is no way for Visual Studio to detect it. With the way that the changes are notified to the UI, if you enter an incorrect string there is no warning or error thrown, the UI component simply does not update. This can be difficult to diagnose as even by scanning the code it is not always obvious.

In the example below we use the nameof operator to replace the string in the call to RaisePropertyChanged with the name of the property. This is taken from an upgraded version of the above app that is written for Windows 10.

private string currentLapTime;

public string CurrentLapTime
{
    get { return currentLapTime; }
    set
    {
        currentLapTime = value;
        RaisePropertyChanged(nameof(CurrentLapTime));
    }
}

Now not only do we have the reassurance that we cant insert a bug with a typo in the string, we are able to change the property names in our code without having to concern ourselves with changing the strings in our calls to RaisePropertyChanged.

Null-conditional operator

The null-conditional operator is written in code as ?. it is also called the “Elvis” operator, but I have no idea why. This operator allows you to call┬ámethods and access members, but if the evaluation would throw a NullReferenceException, it instead returns null.

The example below would return a NullReferenceException

public string Example()
{
    DirectoryInfo dirInfo = new DirectoryInfo(@"C:Test");
    var files = dirInfo.GetFiles("*.zip");

    return files.FirstOrDefault().Name;
}

Now we could get round this with some defensive code and check that files contains values before returning the string. However, using the null-conditional operator we can simply modify our code to return null for us as in the example below:

public string Example()
{
    DirectoryInfo dirInfo = new DirectoryInfo(@"C:Test");
    var files = dirInfo.GetFiles("*.zip");

    return files.FirstOrDefault()?.Name;
}

The code above now will not throw an exception, but will simply return null back to the calling method. Simple steps like this can help avoid the errors that are associated when we miss catching a NullReferenceException.

Property initializers

Property initializers allow you to set a default value to an automatic property. Usually people set the initial values of properties in the constructor. Again like the other examples in this post, this can lead to simple errors being added into the code as it could be…

public class Example
{
    public List Names { get; set; }
}

If we tried to add an item to the list in the below example, we would get a NullReferenceException. Using the Null-conditional operator wouldn’t really help us as the list would still be null. To get round this we would initialize the variable in the constructor.

public class Example
{
    public Example()
    {
        Names = new List();
    }

    public List Names { get; set; }
}

This is simple in this example, but problems can still be added later by accident. Another developer may try and clear down the constructor, or create a new constructor that did not implement your original one. As of C# 6.0 we can use the property initializer to set the initial value with the property.

public class Example
{
    public List Names { get; set; } = new List();
}

This keeps the code cleaner and keeps the code together, reducing the risk of it being missed during later maintenance.

Conclusion

The examples in this post don’t cover all the features for C# 6.0, but hopefully just adding some of these to your code will help get improve code quality and reduce unnecessary code in your applications.

 

Here we go

Well this is the start of my blog! I’m a software developer who has worked across a number of technologies including desktop, web, mobile and cloud. Also covering everything from user entry systems to applications that manage and update networks, along with lots of other projects in between.

In my blog I will mostly be covering C#, but will look at various other languages and technologies as I use them for my projects.