SonarLint Visual Studio Extension / C# Linter

I’m currently working on a legacy code base that’s not a shining example of clean code and best practices.

I try to improve the code as I work, a careful balancing act where I do my best not to impact productivity by spending too much time on refactoring and reformatting.

To help me with this task I decided to look into linters. Note that I’m not using ReSharper which would help with code quality, but that’s another story.

I tried StyleCop, but with the default settings I just wasn’t impressed. Many rules are in my opinion needlessly restrictive. It also seemed to simply dump more than a thousand warnings in the error window.

I tried SonarLint next and I must say I was thoroughly impressed. Though the errors are also sent to the error window they are also shown inline in the file. The parsing by SonarLint was fast and running the Visual Studio extension only had a very small impact on performance even while working with a solution containing thousands of files and hundreds of thousands of lines of codes.

While I haven’t run ReSharper in years, performance was one of the two reasons I stopped using it. On large solutions like the one I’m currently working with, it would slow everything down to a crawl, even when disabling solution-wide analysis.

SonarLint isn’t exactly what I was expecting it to be. I thought it would be more for style guidelines but it has instead given me deeper insights. I’m specifically referring to my last two examples.

Things like needlessly nested if statements:

if (FirstProperty == false) 
{
    if (NeedlesslyDeeplyScoped == true)
    { }
}

Using a Count() instead of an Any:

if (files.Count(f => f.IsDeleted) > 0)
// to
if (files.Any(f => f.IsDeleted))

To foreach statements that can run on null variables:

List<Foo> myCollection = null;

if (IsWeatherRainy) 
{
    myCollection = new List<Foo>();
    // add stuff
}

// myColllection null on at least one execution path
foreach (var item in myCollection)

Or overlapping method signatures with optional parameters that can’t be used:

// This method's signature overlaps the second one
// and the default parameter value can't be used
public File GetFile(bool firstParam, 
                    bool secondParam = false)
{
    return new File();
}

public TestFile GetFile(bool firstParam)
{
    return new TestFile();
}

This last one having been found three times in a single file.

SonarLint is available on the Visual Studio marketplace. It’s free and open source with a repository on GitHub. It’s created by a company that also sells a similar product (though geared towards CI / Build servers) but I haven’t found any downsides to using the free Visual Studio Extension.

By the way, I haven’t been asked to write this by the company that makes SonarLint.

JavaScript tip 4: use let and const

ES6 (aka. ECMAScript 2015, 6th edition) introduced the let and const statements.

These are meant as alternatives to var and baring browser compatibility issues, I recommend that you should be using them over var.

Speaking of browser compatibility, modern browsers support them, the main pain point being IE version 10 and older. Sadly some of us (ahem… yours truly) still sometimes work on intranet applications that must support older browsers so I mention it.

The difference between let and var is that let is scoped to the current scope (function, block, expression) while var is scoped to it’s containing function or barring that globally.

Here are some examples of behaviour which people not used to var‘s scoping might find odd:

function test1() {
  var foo = 1;

  if (true) {
    var foo = 2;
  }

  console.log(foo);  
}

test1();

function test2() {
  let foo = 1;

  if (true) {
    let foo = 2;
  }

  console.log(foo);  
}

test2();

Here test1() returns 2 even though the second foo declaration was in an inner scope. test2() on the other hand returns 1 has the second foo is scoped to it’s containing if statement.

Here is another example:

function test3() {
  for (var i = 0; i < 10; i++) {
    var inner = i;  
  }
    
  console.log(inner);
}

test3();

function test4() {
  for (let i = 0; i <= 10; i++) {
    let inner = i;  
  }
  
  console.log(inner);
}

test4();

In test3(), the output is 9 which is the last value of i in the loop’s inner scope. test4() returns an inner is not defined error which is more appropriate.

const scoping rules work like let but:

  • You must assign a value at declaration
  • You cannot re-assign a new value later on

This behaviour is similar to readonly and const in other languages like C# and affords an extra level of security for values that cannot change.

Writing a simple Sudoku solver in F#

To continue learning about F# and to practice programming functionally, I have written a simple Sudoku solver. I use the word simple, because some simple Sudoku problems can be solved only by going over the board and removing entries without having to make “guesses” and backtracking.

This guessing and backtracking usually involves implementing a depth-first search when writing a Sudoku algorithm.

In the interest of time (there’s another project which I have been delaying for months and need to be starting) I have only implemented a solution to the easy type of Sudokus.

The first part is writing code that checks whether a board is correctly solved. This part can be done first and it’s better to do so since we will need it to check whether our Sudoku solver actually works.

The process is pretty easy, in Board.fs I implement the types I need to represent the board (Value) and it’s state (BoardSolved).

Checking the board implies collecting all it’s rows, columns and boxes (which are nine 3×3 regions on the board) and then checking them for duplicates.

To solve a board we go over all rows, columns and boxes and for each item in these collections we remove from the list of possible values those values which have already been selected in another item. I call this “locking” the values.

This operation is applied successively until the board is solved. The most complicated part came because I used a 2D array to represent the board but I needed to convert the rows, columns and boxes values to lists. Converting the lists generated from the boxes was the single most complicated and longest part of the whole program.

I guess it pays to just use lists for everything and skip on using arrays. The language and it’s libraries are pretty much made for working with lists and sequences so when you deviate from that you end up having to write additional code.

Here is the GitHub repo with the whole thing.

To make this solver capable of solving any Sudoku, we would need to change the

| BoardUnlocked -> failwith “Board not yet solved”

line with calling a depth-first search which would select the first unlocked value, try and select the first possible value for this item and then continue recursively trying to solve the board until either it succeeds or it fails. When/if it fails backtrack and continue it’s search using another value.