[英]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;博士
您可以安全地从方法签名中删除此属性。
解释
在您的CompareTo
方法签名中,该结构是按值传递的,并且未标记为可为空。 这是PackageVersionNumber
结构的正确接口实现。
这意味着,无论您做什么, other
参数值都不能是null
。
你甚至不能写if (other == null)
- 这会产生编译器错误(除非你为PackageVersionNumber
重载==
运算符,顺便说一下你应该真正考虑的结构)。
但即使使用重载的==
运算符, if (other == null)
比较总是会产生false
- 所以不需要检查。 重载运算符将允许编译器将PackageVersionNumber
隐式转换为可为空PackageVersionNumber?
在比较中 - 你会得到一个 CS0472 警告:
表达式的结果始终为“假”,因为“PackageVersionNumber”类型的值永远不会等于“PackageVersionNumber?”类型的“null”。
我想 Visual Studio 中的“实现接口”功能不考虑实现接口的类型,并且始终使用与AllowNullAttribute
相同的代码段。
该属性对于实现不可为空的引用类型的接口确实很有用。 虽然它们是“逻辑上”不可为空的,但仍有一种方法可以在运行时获取null
值 - 因此需要进行 null 检查以避免NullReferenceException
。 此外,您必须确保与使用 C#7.x 及更低版本编译的程序集的向后兼容性 - IComparable<T>
完全允许null
用于引用类型的T
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.