Nullability headaches with IComparer and IEqualityComparer #103787
Replies: 8 comments 13 replies
-
Tagging subscribers to this area: @dotnet/area-system-collections |
Beta Was this translation helpful? Give feedback.
-
Why do you think it's useless? It indicates that if you were to pass your implementation to a collection that does run equality comparisons against null values, your code wouldn't be able to handle them. The contract for IEqualityComparer expects that null values should be accepted. |
Beta Was this translation helpful? Give feedback.
-
Defense in depart is always a good thing. There’s no guarantee a null didn’t make it in the |
Beta Was this translation helpful? Give feedback.
-
@RenderMichael : My most immediate encounter of it was a case where any object not in the list being sorted would be doomed to failure as I actually have to parse the string to order by it; checking for null doesn't really help. |
Beta Was this translation helpful? Give feedback.
-
You can turn a hard-to-diagnose |
Beta Was this translation helpful? Give feedback.
-
Hint to anybody trying to answer this: if you answer doesn't handle the IEqualityComparer.GetHashCode case where the static typing says it can't be null but it definitely can be null (I can put a breakpoint on the return statement in So far everybody's trying to say IComparer.Compare should always handle nulls; think about what the equivalent to that is for IEqualityComparer.GetHashCode ; and no changing the interface type is not an answer there; most of the time these are stock implementations of IEqualityComparer. |
Beta Was this translation helpful? Give feedback.
-
It sounds like the disagreement here is with the nullability annotations placed on two specific types in the BCL, not with NRT broadly. You can make a proposal to change the annotations for The proposal could look something like this: namespace System.Collections.Generic
public interface IComparer<T>
{
public int Compare(
#nullable disable
T x,
T y
#nullable restore
);
}
public interface IEqualityComparer<T>
{
public bool Equals(
#nullable disable
T x,
T y
#nullable restore
);
} |
Beta Was this translation helpful? Give feedback.
-
Well, according to the IEqualityComparer<T>.GetHashCode documentation, an implementation is supposed to throw an ArgumentNullException when a null reference is passed to it: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.iequalitycomparer-1.gethashcode#exceptions |
Beta Was this translation helpful? Give feedback.
-
We currently have:
The nullable annotations are messed up in the stock methods.
Demonstration:
IEqualityComparer has the opposite problem as well:
Both of these came up in real code multiple times. We've been slow to adapt nullability checks due to false alarms and false IDE automated fixes to them (but the latter is another story).
In general, these two are the same problem. I had both of these come up in live code with these exact use cases.
The problem is the nullability of the arguments doesn't correspond to the nullability of the interface. If the enumerable cannot contain a null; its OrderBy() comparer need not support nulls; and the inverse: if the dictionary key is allowed to be null then IEqualityComparer.GetHashCode() can receive a null. There's no way to shut up the compiler other than manually suppressing the warnings because the warnings are wrong because nullability needs to actually follow the type.
Beta Was this translation helpful? Give feedback.
All reactions