Skip to main content

Null Reference Analysis

  • 5 minutes to read

CodeRush includes the CRR0027 - Possible System.NullReferenceException analyzer. This analyzer detects unprotected code that can potentially raise a System.NullReferenceException exception.

To enable this analyzer, choose the Possible System.NullReferenceException issue in the Editor | Language | Code Analysis | Code Issues Catalog options page, check the Enabled checkbox, and click OK.

Enable

You can analyze a solution, an active project, or an active document in the Code Issues window. To invoke this window, open the CodeRush menu and choose the Code Analysis | Code Issues menu item.

CodeIssues_main

Note

CodeRush menu is placed in the Visual Studio Extensions menu for Visual Studio 2019. You can restore the default CodeRush menu position in Visual Studio 2019 16.4 or later. See the First Steps topic for more information.

In the Code Issues window, click the Refresh button to start code analysis.

Start Analysis

Null Reference Analysis Modes

CodeRush can analyze values in Trusting, Skeptical, and Thorough diagnostic modes. You can specify the Possible System.NullReferenceException diagnostic mode for methods, properties, parameters, fields, and local variables in the Editor | Language | Code Analysis | Possible NullReferenceException options page.

Options

The following sections describe each diagnostic mode:

Trusting

If an element is not checked for null in the current scope and does not have the [CanBeNull] attribute, the analyzer trusts this element and does not show the diagnostic in the Code Issues window.

In the example below, the SortElements method does not provide information whether Elements are null or not. The Possible System.NullReferenceException analyzer considers Elements as not null in Trusting mode and does not show the diagnostic in the Code Issues window.

class TrustingMode {
    public List<string> Elements { get; set; }

    public void SortElements() {
        Elements.Sort();
    }
}

The analyzer shows the CRR0027 - Possible System.NullReferenceException diagnostic in Trusting mode, for example, if the following code has a null check error:

class TrustingMode {
    public List<string> Elements { get; set; }

    public void SortElements() {
        if (Elements == null)
            Elements.Sort();
    }
}

The Code Issues window looks as follows:

CodeIssues_main

You can mark the Elements property with the [CanBeNull] code annotation attribute to indicate this property can be null.

class TrustingMode {
    [CanBeNull]
    public List<string> Elements { get; set; }

    public void SortElements() {
        Elements.Sort();
    }
}

In this case, the analyzer shows the diagnostic even if the code does not have a null check expression.

CodeIssues_main

Skeptical

If an element is not checked for null in the current scope, the analyzer does not show the diagnostic for elements that have the [NotNull] attribute.

In the example below, the Elements property is not checked for null.

class SkepticalMode {
    public List<string> Elements { get; set; }

    public int GetEmptyElementCount() {
        var count = 0;

        foreach (var element in Elements) {

            if (string.IsNullOrEmpty(element))
                count++;
        }
        return count;
    }
}

The analyzer shows the diagnostic for the Elements property in this case:

CodeIssues_main

If you do not want the analyzer to show this diagnostic, add the null check.

class SkepticalMode {
    public List<string> Elements { get; set; }

    public int GetEmptyElementCount() {
        var count = 0;

        if (Elements == null)
            return 0;

        foreach (var element in Elements) {

            if (string.IsNullOrEmpty(element))
                count++;
        }
        return count;
    }
}

You can also use the [NotNull] code attribute to indicate the Elements property is not null.

class SkepticalMode {

    [NotNull]
    public List<string> Elements { get; set; }

    public int GetEmptyElementCount() {
        var count = 0;        

        foreach (var element in Elements) {

            if (string.IsNullOrEmpty(element))
                count++;
        }
        return count;
    }
}

Thorough

If an element is not checked for null in the current scope and the element does not have the [CanBeNull] or [NotNull] attribute, the analyzer checks if the element can never be null (lazy initialized, returns new created object, etc). The mode works more slowly than others.

In the following code, the analyzer shows the diagnostic in Skeptical mode but does not show it in Thorough mode because the Elements property always returns a non-null value.

class ThoroughMode {

    List<string> elements;

    public List<string> Elements {

        get

        {   
            if (elements == null)
                elements = new List<string>();
            return elements;
            }
        }

    public int GetEmptyElementCount() {

        var count = 0;

        foreach (var element in Elements) {

            if (string.IsNullOrEmpty(element))

                count++;
        }
        return count;
    }
}

Annotation Attributes

CodeRush checks annotation attributes by a partial name. This means you do not need to reference annotations, just declare them in code.