
Inline adoc files when they are included exactly once. Also fix language tags because this inlining gives us better information on what language the code is written in.
108 lines
2.8 KiB
Plaintext
108 lines
2.8 KiB
Plaintext
== Why is this an issue?
|
|
|
|
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.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,csharp]
|
|
----
|
|
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
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,csharp]
|
|
----
|
|
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
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
=== Exceptions
|
|
* Arguments validated for `null` via helper methods should be annotated with the https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/nullable-analysis#postconditions-maybenull-and-notnull[`[NotNull]`] attribute.
|
|
* Method parameters marked with the `[NotNull]` https://www.jetbrains.com/help/resharper/Reference__Code_Annotation_Attributes.html#ItemNotNullAttribute[Resharper code annotation attribute] are supported as well.
|
|
* To create a custom null validation method declare an attribute with name `ValidatedNotNullAttribute` and mark the parameter that is validated for null in your method declaration with it:
|
|
|
|
[source,csharp]
|
|
----
|
|
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
|
|
}
|
|
}
|
|
----
|
|
|
|
|
|
include::../rspecator.adoc[]
|