Visual Studio shows compiler warning CS04721 under (int)5 == null
which reads
The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?'
bool x = (int)5 == null;
However, there is no warning if a DateTime
object is used.
bool y = DateTime.UtcNow == null;
Since DateTime
is not Nullable<DateTime>
, it can never be null. What's the reason a similar warning is not shown for the second statement?
CodePudding user response:
The code
bool x = (int)5 == null;
produces the warning number CS0472
which has existed since the first version of C#.
The code
bool y = DateTime.UtcNow == null;
produces the warning number CS8073
. According to its help page, the warning CS8073
is part of the "warning wave 5" and was only introduced with C# version 9.
So you will see the warning when using C# 9 or newer and you won't see it when using older versions.
Whether you see the warning will also be influenced by the " AnalysisLevel" you configure in the project options of your project. To see warning CS8073
, you should have enabled warning level 5 or higher.
Warning CS8073
specifically applies to struct types while the older warning deals with built-in primitive value types.
There is a blog post by Microsoft that announces the introduction of new warnings. According to the blog post, warning CS8073
was introduced because it deals with a "common coding mistake".
Why the warning hasn't been implemented earlier can only be guessed. My guess is the following:
The comparison operator from the first example with the type int
is built into the language, while the equality operator in the second example is an operator overload in the class DateTime
that is implemented as C# code in the .net Framework source code.
So, in order to generate the warning in the second case, the Compiler has to look at the actual implementation of the struct type and its available operator overloads.
There could in fact be an overload that allows using the equality operator with a struct type and a different reference type in which case the warning would not be justified because the comparison with null
could return true
.
Example of a program where the comparison of a struct type
with null
will return true
(Nullable option is disabled):
internal class Program
{
public struct X
{
public static bool operator ==(X s1, object s2) => s1.Equals(s2);
public static bool operator !=(X s1, object s2) => s1.Equals(s2);
public override bool Equals(object other) => true;
public override int GetHashCode() => 0;
}
static void Main()
{
X x = new X();
bool b = x == null;
Console.WriteLine(b);
}
}