在 C# 8 的结构上正确实现 IComparable<T>,并将 Nullable 设置为启用
Properly implementing IComparable<T> on a Struct in C# 8 with Nullable set to enable
启用 Nullable 后,现在在 C# 8 中实现 CompareTo 的正确方法是什么。 Visual Studio 中的实现接口功能建议使用此签名:
public struct PackageVersionNumber : IComparable<PackageVersionNumber>
{
public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public int CompareTo([AllowNull] PackageVersionNumber other)
{
// ...
}
}
PackageVersionNumber 在这种情况下是一个结构,实际上不应该为 null。我可以安全地从参数中删除 [AllowNull]
属性,还是需要将其保留在那里并真正检查是否为 null。或者这是一个错误?
TL;DR
您可以安全地从方法签名中删除此属性。
说明
在您的 CompareTo
方法签名中,结构按值传递并且未标记为可为空。这是您的 PackageVersionNumber
结构的正确接口实现。
也就是说,无论你做什么,other
参数值都不能是null
。
你甚至不能写 if (other == null)
- 这会产生编译器错误(除非你为 PackageVersionNumber
重载 ==
运算符,顺便说一句,你应该真正考虑结构).
但即使使用重载的 ==
运算符,if (other == null)
比较也会 总是 产生 false
- 所以没有必要这样做查看。重载运算符将允许编译器在比较中将 PackageVersionNumber
隐式转换为可为空的 PackageVersionNumber?
- 您将收到 CS0472 警告:
The result of the expression is always 'false' since a value of type 'PackageVersionNumber' is never equal to 'null' of type 'PackageVersionNumber?'
我想 Visual Studio 中的 "Implement interface" 特性没有考虑实现接口的类型,并且总是使用与 AllowNullAttribute
相同的片段。
该属性对于实现不可为 null 的引用类型的接口确实很有用。虽然它们 "logically" 不可为 null,但仍有一种方法可以在运行时获取 null
值 - 因此需要进行 null 检查以避免 NullReferenceException
。此外,您必须确保与使用 C#7.x 及更低版本编译的程序集的向后兼容性 - IComparable<T>
完全允许 null
用于 T
引用类型。
启用 Nullable 后,现在在 C# 8 中实现 CompareTo 的正确方法是什么。 Visual Studio 中的实现接口功能建议使用此签名:
public struct PackageVersionNumber : IComparable<PackageVersionNumber>
{
public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public int CompareTo([AllowNull] PackageVersionNumber other)
{
// ...
}
}
PackageVersionNumber 在这种情况下是一个结构,实际上不应该为 null。我可以安全地从参数中删除 [AllowNull]
属性,还是需要将其保留在那里并真正检查是否为 null。或者这是一个错误?
TL;DR
您可以安全地从方法签名中删除此属性。
说明
在您的 CompareTo
方法签名中,结构按值传递并且未标记为可为空。这是您的 PackageVersionNumber
结构的正确接口实现。
也就是说,无论你做什么,other
参数值都不能是null
。
你甚至不能写 if (other == null)
- 这会产生编译器错误(除非你为 PackageVersionNumber
重载 ==
运算符,顺便说一句,你应该真正考虑结构).
但即使使用重载的 ==
运算符,if (other == null)
比较也会 总是 产生 false
- 所以没有必要这样做查看。重载运算符将允许编译器在比较中将 PackageVersionNumber
隐式转换为可为空的 PackageVersionNumber?
- 您将收到 CS0472 警告:
The result of the expression is always 'false' since a value of type 'PackageVersionNumber' is never equal to 'null' of type 'PackageVersionNumber?'
我想 Visual Studio 中的 "Implement interface" 特性没有考虑实现接口的类型,并且总是使用与 AllowNullAttribute
相同的片段。
该属性对于实现不可为 null 的引用类型的接口确实很有用。虽然它们 "logically" 不可为 null,但仍有一种方法可以在运行时获取 null
值 - 因此需要进行 null 检查以避免 NullReferenceException
。此外,您必须确保与使用 C#7.x 及更低版本编译的程序集的向后兼容性 - IComparable<T>
完全允许 null
用于 T
引用类型。