Methods declared as public, protected, or protected internal can be accessed from other assemblies, which
means you should validate parameters to be within the expected constraints. In general, checking against null is recommended in defensive
programming.
This rule raises an issue when a parameter of a publicly accessible method is not validated against null before being
dereferenced.
public class MyClass
{
private MyOtherClass other;
public void Foo(MyOtherClass other)
{
this.other = other.Clone(); // Noncompliant
}
protected void Bar(MyOtherClass other)
{
this.other = other.Clone(); // Noncompliant
}
}
public class MyClass
{
private MyOtherClass other;
public void Foo(MyOtherClass other)
{
if (other != null)
{
this.other = other.Clone();
}
}
protected void Bar(MyOtherClass other)
{
if (other != null)
{
this.other = other.Clone();
}
}
public void Baz(MyOtherClass other)
{
ArgumentNullException.ThrowIfNull(other);
this.other = other.Clone();
}
public void Qux(MyOtherClass other)
{
this.other = other; // Compliant: "other" is not being dereferenced
}
private void Xyzzy(MyOtherClass other)
{
this.other = other.Clone(); // Compliant: method is not publicly accessible
}
}
null via helper methods should be annotated with the [NotNull] attribute. [NotNull] Resharper code annotation
attribute are supported as well. ValidatedNotNullAttribute and mark the parameter that is
validated for null in your method declaration with it:
using System;
[AttributeUsage(AttributeTargets.Parameter, Inherited=false)]
public sealed class ValidatedNotNullAttribute : Attribute { }
public static class Guard
{
public static void NotNull<T>([ValidatedNotNullAttribute] T value, [CallerArgumentExpression("value")] string name = "") where T : class
{
if (value == null)
throw new ArgumentNullException(name);
}
}
public static class Utils
{
public static string ToUpper(string value)
{
Guard.NotNull(value);
return value.ToUpper(); // Compliant
}
}