I'm running my project in a nullable enabled context and I wish to simplify my code because it's internal and I KNOW that the references passed in are non-null. The IEqualityComparer interface gives warnings if I make the parameters not nullable.
class FileInfoComparer : IEqualityComparer<FileInfo>
{
// Round up timestamp to the next 2 seconds
const long interval = 20_000_000;
DateTime RoundUp(DateTime time) => time.AddTicks(interval - (time.Ticks - 1) % interval - 1);
public bool Equals(FileInfo? fi1, FileInfo? fi2)
{
return fi1.Name == fi2.Name &&
RoundUp(fi1.LastWriteTime) == RoundUp(fi2.LastWriteTime) && fi1.Length == fi2.Length;
}
public int GetHashCode(FileInfo fi)
{
return HashCode.Combine(fi.Name, RoundUp(fi.LastWriteTime), fi.Length);
}
}
As it stands I'm getting squigglies under various fi1 and fi2 references whenever I try to make them not nullable. I've tried adding various attributes like [NotNull] in places but nothing works. I've also tried writing like this:
return fi1?.Name == fi2?.Name &&
RoundUp(fi1.LastWriteTime) == RoundUp(fi2.LastWriteTime) && i1.Length == fi2.Length;
but the squigglies just move somewhere else. Are there any Null attributes like [DisallowNull] etc. that I can add in the right places to remove the warnings?
CodePudding user response:
/// <remarks>
/// <see cref="Equals"/> rejects <see langword="null"/> values.
/// </remarks>
class FileInfoComparer : IEqualityComparer<FileInfo>
{
// Other parts as before
public bool Equals(FileInfo? fi1, FileInfo? fi2)
{
if (fi1 is null)
{
throw new ArgumentNullException(nameof(fi1));
}
if (fi2 is null)
{
throw new ArgumentNullException(nameof(fi2));
}
return fi1.Name == fi2.Name &&
RoundUp(fi1.LastWriteTime) == RoundUp(fi2.LastWriteTime) && fi1.Length == fi2.Length;
}
// GetHashCode as before
}
It is possible to make the argument validation a single line if desired by turning it into a method that takes a parameter and throws if it is null.
Alternative using the null forgiving operator:
/// <remarks>
/// <see cref="Equals"/> rejects <see langword="null"/> values.
/// </remarks>
class FileInfoComparer : IEqualityComparer<FileInfo>
{
// Other parts as before
public bool Equals(FileInfo? fi1, FileInfo? fi2)
{
return fi1!.Name == fi2!.Name &&
RoundUp(fi1.LastWriteTime) == RoundUp(fi2.LastWriteTime) && fi1.Length == fi2.Length;
}
// GetHashCode as before
}