== Why is this an issue?

In C#, without constraints on a generic type parameter, both https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types[reference] and https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types[value] types can be passed. However, comparing this type parameter to `null` can be misleading as value types, like `struct`, can never be null.

== How to fix it

To avoid unexpected comparisons:

* if you expect a value type, use https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default#default-operator[default()] for comparison
* if you expect a reference type, add a https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters[constraint] to prevent value types from being passed

=== Code examples

==== Noncompliant code example

[source,csharp,diff-id=1,diff-type=noncompliant]
----
bool IsDefault<T>(T value)
{
  if (value == null) // Noncompliant
  {
    // ...
  }
}
----

==== Compliant solution

[source,csharp,diff-id=1,diff-type=compliant]
----
bool IsDefault<T>(T value)
{
  if (EqualityComparer<T>.Default.Equals(value, default(T)))
  {
    // ...
  }
}
----

or

[source,csharp]
----
bool IsDefault<T>(T value) where T : class
{
  if (value == null)
  {
    // ...
  }
}
----

== Resources

=== Documentation

* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters[Constraints on type parameters]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/reference-types[Reference types]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/value-types[Value types]
* Microsoft Learn - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/default#default-operator[`default` operator]

include::../rspecator.adoc[]
