What should IEquatable<T>.Equals(T obj) do when this == null and obj == null?
1) This code is generated by F# compiler when implementing IEquatable<T>. You can see that it returns true when both objects are null:
public sealed override bool Equals(T obj)
{
if (this == null)
{
return obj == null;
}
if (obj == null)
{
return false;
}
// Code when both this and obj are not null.
}
2) Similar code can be found in the question “in IEquatable implementation is reference check necessary” or in the question “Is there a complete IEquatable implementation reference?“. This code returns false when both objects are null.
public sealed override bool Equals(T obj)
{
if (obj == null)
{
return false;
}
// Code when obj is not null.
}
3) The last option is to say that the behaviour of the method is not defined when this == null.
leppie is right. Just to elaborate on his answer (and confirm his suspicion that F# doesn’t guarantee
this != null): discriminated unions may be marked with the attribute[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]allowing cases to be represented by the value null.Option<'T>is such a type. TheNonecase is represented by null at run-time.(None : option<int>).Equals(None)is syntactically valid. Here’s a fun example:Decompiling
ThisIsNullwith Reflector showsAnd the result: