7
votes

I just updated Visual Studio to latest 16.6.0 Preview 1.0 with latest .NET Core 3.1.2. My project has <Nullable>enable</Nullable>.

It seems there has been a change to IEquatable<T> and now it is defined with [AllowNull]:

public interface IEquatable<T>
{
  bool Equals([AllowNull] T other);
}

As a result, any class of mine which implemented IEquatable<T> with bool Equals(T o) now shows a warning:

CS8767: Nullability of reference types in type of parameter 'o' of 'bool MyType.Equals(MyType o)' doesn't match implicitly implemented member 'bool IEquatable.Equals(MyType other)' because of nullability attributes.

What is the best way to solve this ?

I can add a nullable operator bool Equals(T? o), or I can add [AllowNull] (with reference to System.Diagnostics.CodeAnalysis). Both seem to make the warning go away, but I'm not sure which one is better.

Also, I now opened the door for a null parameter which I didn't really want.

1
I realized that nullability checking and generics is still a hard living...Mario Vernari
'bug' ? 'fixed' ? Do you have any reference for this ?kofifus
Add [AllowNull] to your Equals methodJulien Couvreur
Can the you share the entire code sample? With your types implementing IEquatable<T>Pavel Anikhouski

1 Answers

2
votes

The convention for IEquatable<T>.Equals is that the argument can be null. If T is a reference type, just annotate it with ? and the warning will go away. The following compiles just fine:

#nullable enable

using System;

public class C1 : IEquatable<C1>
{
    public bool Equals(C1? c) => false;
}

public struct C2 : IEquatable<C2>
{
    public bool Equals(C2 c) => false;
}

https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4GIB2BXANliwtwAEcaeBAsAFBUACATAIxW0DMh9hAwg4SIQJIBRAI4YIMMnAA83AHxUA3lUIr2bYAHsNWQiLFYoACm4B+QgGMAlIQC8swgDMIBuAG4qAX2aUabWAgxzGC46XgE9cUkZOnlKJUpVNUJNbV1RZyNOUKtbeycXd0ovSiA=