When to specify the restriction `T: IEquatable <T>`, although it is not strictly required?
In short, I'm looking for guidance on which of the following two methods should be preferred (and why):
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);
}
Argument in favor
DistinctA: Obviously, a restriction on isTnot required, because itHashSet<T>does not require it, and because instances of any oneTcan be guaranteed to be converted toSystem.Object, which provides the same functions asIEquatable<T>(namely, the two methodsEqualsandGetHashCode). (While non-generic methods will invoke boxing with value types, this is not what concerns me here.)The argument in favor of
DistinctB: limiting the overall parameter, although not necessarily, makes visible to callers that the method will compare the itemsTand, therefore, is a signal thatEqualsandGetHashCodeshould work correctly forT. (After all, the definition of a new type without explicit implementationEqualsandGetHashCodeis very easy, so the limit can help catch some bugs before.)
Question: Is there an established and documented best practice that recommends when to specify this restriction ( T : IEquatable<T>) and when not? And if not, is any of the above arguments incorrect? (In this case, I would prefer thoughtful arguments rather than just personal opinions.)