单个泛型的 Comparable 和 Nullable 约束

Comparable and Nullable constraints on single generic

我想编写一个扩展方法,将一个值与另外两个值进行比较,并确定该值是否在另外两个值之内。这适用于此目的

public static bool IsWithin<T>(this T value, T min, T max) where T : IComparable<T>
{
    return (bool)(value.CompareTo(min) > 0 && value.CompareTo(max) < 0);
}

我还想扩展此方法以在 Nullable<T> 上工作。如果值为空,我希望忽略任何一个边界条件。我曾尝试对 T 施加额外的约束,但这不受支持。下面的代码无法通过编译,但这是我想要实现的。

public static bool IsWithinInclusive<T>(this T value, Nullable<T> min, Nullable<T> max) where T : IComparable<T>
{
    return (bool)(
        (min.HasValue ? value.CompareTo(min) >= 0 : true) && 
        (max.HasValue ? value.CompareTo(max) <= 0 : true));
}

是否可以编写一个实现此目的的方法?

您需要将 T 限制为 struct 以匹配 definition of Nullable<T>:

public static bool IsWithinInclusive<T>(this T value, Nullable<T> min, Nullable<T> max) where T : struct, IComparable<T>
{
    return 
        (min.HasValue ? value.CompareTo(min.Value) >= 0 : true) && 
        (max.HasValue ? value.CompareTo(max.Value) <= 0 : true);
}

您还需要使用 .ValueNullable<T> 中获取 T

正如 SLaks 回答的那样,Nullable<T>(或只是 T?)不被接受的原因是因为这要求 T 是不可空的值类型。不能用单一方法同时覆盖值类型和引用类型:你想支持的值类型不能表示null,引用类型不能支持T?,所以你无法避免有两种不同的方法。

但是,您可以两次使用完全相同的函数体,让reader明白这两个重载做同样的事情:

public static bool IsBetween<T>(this T value, T min, T max) where T : IComparable<T>
{
    return (min == null || value.CompareTo((T)min) >= 0)
        && (max == null || value.CompareTo((T)max) <= 0);
}

public static bool IsBetween<T>(this T value, T? min, T? max) where T : struct, IComparable<T>
{
    return (min == null || value.CompareTo((T)min) >= 0)
        && (max == null || value.CompareTo((T)max) <= 0);
}