coderushforroslyn-401603-static-code-analysis-null-reference-analysis.md
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.
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.
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.
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.
The following sections describe each diagnostic mode:
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();
}
}
Class TrustingMode
Public Property Elements As List(Of String)
Public Sub SortElements()
Elements.Sort()
End Sub
End Class
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();
}
}
Class TrustingMode
Public Property Elements As List(Of String)
Public Sub SortElements()
If Elements Is Nothing Then Elements.Sort()
End Sub
End Class
The Code Issues window looks as follows:
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();
}
}
Class TrustingMode
<CanBeNull>
Public Property Elements As List(Of String)
Public Sub SortElements()
Elements.Sort()
End Sub
End Class
In this case, the analyzer shows the diagnostic even if the code does not have a null check expression.
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;
}
}
Class SkepticalMode
Public Property Elements As List(Of String)
Public Function GetEmptyElementCount() As Integer
Dim count = 0
For Each element In Elements
If String.IsNullOrEmpty(element) Then count += 1
Next
Return count
End Function
End Class
The analyzer shows the diagnostic for the Elements property in this case:
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;
}
}
Class SkepticalMode
Public Property Elements As List(Of String)
Public Function GetEmptyElementCount() As Integer
Dim count = 0
If Elements Is Nothing Then Return 0
For Each element In Elements
If String.IsNullOrEmpty(element) Then count += 1
Next
Return count
End Function
End Class
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;
}
}
Class SkepticalMode
<NotNull>
Public Property Elements As List(Of String)
Public Function GetEmptyElementCount() As Integer
Dim count = 0
For Each element In Elements
If String.IsNullOrEmpty(element) Then count += 1
Next
Return count
End Function
End Class
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;
}
}
Class ThoroughMode
Private elements As List(Of String)
Public ReadOnly Property Elements As List(Of String)
Get
If elements Is Nothing Then elements = New List(Of String)()
Return elements
End Get
End Property
Public Function GetEmptyElementCount() As Integer
Dim count = 0
For Each element In Elements
If String.IsNullOrEmpty(element) Then count += 1
Next
Return count
End Function
End Class
CodeRush checks annotation attributes by a partial name. This means you do not need to reference annotations, just declare them in code.