何时指定约束`T:IEquatable <T>`,即使它不是严格要求的?

sta*_*ica 5 c# generics iequatable type-constraints type-parameter

简而言之,我正在寻找以下两种方法中哪一种应该是首选的指导(以及为什么):

static IEnumerable<T> DistinctA<T>(this IEnumerable<T> xs)
{
    return new HashSet<T>(xs);
}

static IEnumerable<T> DistinctB<T>(this IEnumerable<T> xs) where T : IEquatable<T>
{
    return new HashSet<T>(xs);
}
Run Code Online (Sandbox Code Playgroud)
  • 赞成的论据DistinctA:显然,约束T不是必需的,因为HashSet<T>它不需要它,并且因为任何实例T都保证可转换为System.Object,它提供与IEquatable<T>(即两种方法EqualsGetHashCode)相同的功能.(虽然非泛型方法会导致拳击与值类型,这不是我在这里关注的.)

  • 赞成的DistinctB参数:泛型参数约束虽然不是绝对必要的,但是使调用者可以看到该方法将比较实例T,因此是一个正确EqualsGetHashCode应该正常工作的信号T.(毕竟,在没有明确实现的情况下定义一个新类型Equals并且GetHashCode非常容易发生,因此约束可能有助于及早发现一些错误.)

问题:是否存在建立和记录的最佳实践,建议何时指定此特定约束(T : IEquatable<T>),何时不指定?如果没有,上述论点之一是否有任何缺陷?(在这种情况下,我更喜欢经过深思熟虑的论点,而不仅仅是个人意见.)

Pie*_*ens 2

首先考虑何时使用这两种机制中的哪一种可能很重要;我能想到的只有两个:

  1. 当代码被翻译成另一种语言时(C# 的后续版本,或 Java 等相关语言,或 Haskell 等完全不同的语言)。在这种情况下,通过为翻译人员(无论是自动翻译还是手动翻译)提供更多信息,第二个定义显然更好。
  2. 当不熟悉代码的用户阅读代码以了解如何调用该方法时。同样,我相信第二种方法显然更好,因为可以轻松地向此类用户提供更多信息。

我想不出在任何情况下第一个定义会更受欢迎,而且它实际上超出了个人偏好。

其他人的想法?