哪个版本更好:
using System;
namespace Utils.Extensions
{
public static class EnumerableExtensions
{
public static bool Between<T>(this T item, T min, T max) where T : IComparable<T>
{
return item.CompareTo(min) >= 0 && item.CompareTo(max) <= 0;
}
}
}
或
using System;
namespace Utils.Extensions
{
public static class EnumerableExtensions
{
public static bool Between<T>(this IComparable<T> item, T min, T max)
{
return item.CompareTo(min) >= 0 && item.CompareTo(max) <= 0;
}
}
}
我认为两者都应该有用,但我应该使用哪一个?
答案 0 :(得分:3)
我认为第二个更好。 对于不是的类型,它不会使intelliSense
IComparable
建议列表混乱。 (在任何情况下都不会。)
您正在寻找的是IComparable
特有的。
因此,如果您选择的是可读性,那么使用第二种方法就足够了。
答案 1 :(得分:3)
请注意,T
为值类型时使用第二个版本意味着item
将被装箱。将值类型转换为接口总是需要装箱。
我不会过于担心接口的这种情况,但值得注意的是,BCL中几乎每个IComparable<T>
实现都是值类型。只有你可以决定(小)拳击开销是否可以接受。
答案 2 :(得分:2)
两者之间存在明显差异。第一个应该用于实现IComparable<T>
的类型,其中第二个用于IComparable<T>
。
举例A:
IComparable<int> x = 14;
bool y = x.Between(12, 23);
与示例B对比:
int x = 14;
bool y = x.Between(12, 23);
如果您尝试使用第一种技术(通用约束)使用示例A,那么您将获得编译器错误,因为约束需要一个实现IComparable<int>
的类型,而不是{{1本身。
示例B将使用这两种技术进行编译。我建议使用第二种技术,以便它在两种情况下都能正常工作。无论如何,它似乎是惯例,可能是出于这个原因。但是还有其他原因可以避免使用第一个。在您可能希望为特定类型重载方法的情况下,第二种方法可以提供更大的灵活性。
答案 3 :(得分:-1)
我会说第一个,因为它说明了每一个T,其中第二个只说该项应该是IComparable
。确实它应该做同样的事情,但是通过你想说的话,每个T都是IComparable
。第一个更好。