C# 与IComparable一起使用的可为null的泛型类型。可能吗?

C# 与IComparable一起使用的可为null的泛型类型。可能吗?,c#,generics,nullable,icomparable,C#,Generics,Nullable,Icomparable,我正在尝试创建一个简单的钳制(这样我就可以绑定任何可比较的值…主要是针对int、double等数字类型) 问题是,如果我执行以下操作,就会出现错误,但IComparable的CompareTo应该能够处理空值。 Quote:“根据定义,任何对象的比较值都大于null,两个null引用的比较值相等。” 公共静态T形夹(此T值、T最小值、T最大值) 其中T:i可比较 { 如果(比较值(最大值)>0) 返回最大值; 如果(值比较到(最小值)0) 返回最大值; if(比较器比较(值,最小值)

我正在尝试创建一个简单的钳制(这样我就可以绑定任何可比较的值…主要是针对int、double等数字类型)

问题是,如果我执行以下操作,就会出现错误,但IComparable的CompareTo应该能够处理空值。
Quote:“根据定义,任何对象的比较值都大于null,两个null引用的比较值相等。”

公共静态T形夹(此T值、T最小值、T最大值)
其中T:i可比较
{
如果(比较值(最大值)>0)
返回最大值;
如果(值比较到(最小值)<0)
返回最小值;
返回值;
}
私人Int32_拉链;
公共Int32?拉链
{
得到
{
返回_-zip;
}
设置
{
_zip=值。钳位(099999);
}
}

记住,
Int32?
Nullable
的缩写。由于
Nullable
未实现
IComparable
,因此您的代码不会编译

但是,您可以重载该方法:

public static T? Clamp<T>(this T? value, T? min, T? max) 
    where T : struct, IComparable<T> 
{ 
    // your logic...
} 

或者更好的是,将其作为额外重载的一部分,以实现@LBushkin Nullable或T所说的
Clamp
..

?不实现IComparable接口。给定的解决方案是可以的,但是我更喜欢将可空比较逻辑放在一个专门的类中,在后面,也可以用于比较任何可空类型

例如,您可以创建一个通用的可为null的类型比较器类,如下所示:

public class NullableComparer<T> : IComparer<Nullable<T>>
      where T : struct, IComparable<T>
{

     public int Compare(Nullable<T> x, Nullable<T> y)
     {
        //Compare nulls acording MSDN specification

        //Two nulls are equal
        if (!x.HasValue && !y.HasValue)
            return 0;

        //Any object is greater than null
        if (x.HasValue && !y.HasValue) 
            return 1;

        if (y.HasValue && !x.HasValue)
            return -1;

        //Otherwise compare the two values
        return x.Value.CompareTo(y.Value);
     }

}
public static T? Clamp<T>(this T? value, T? min, T? max)
    where T : struct
{
    var comparer = new NullableComparer<T>();

    if (comparer.Compare(value, max) > 0)
        return max;

    if (comparer.Compare(value, min) < 0)
        return min;

    return value;
}
公共类NullableComparer:IComparer
其中T:struct,i可比较
{
公共整数比较(可为null的x,可为null的y)
{
//根据MSDN规范比较空值
//两个空值相等
如果(!x.HasValue&&!y.HasValue)
返回0;
//任何对象都大于null
if(x.HasValue&&!y.HasValue)
返回1;
if(y.HasValue&&!x.HasValue)
返回-1;
//否则,比较两个值
返回x.Value.CompareTo(y.Value);
}
}
在这种情况下,您可以像这样使用此类:

public class NullableComparer<T> : IComparer<Nullable<T>>
      where T : struct, IComparable<T>
{

     public int Compare(Nullable<T> x, Nullable<T> y)
     {
        //Compare nulls acording MSDN specification

        //Two nulls are equal
        if (!x.HasValue && !y.HasValue)
            return 0;

        //Any object is greater than null
        if (x.HasValue && !y.HasValue) 
            return 1;

        if (y.HasValue && !x.HasValue)
            return -1;

        //Otherwise compare the two values
        return x.Value.CompareTo(y.Value);
     }

}
public static T? Clamp<T>(this T? value, T? min, T? max)
    where T : struct
{
    var comparer = new NullableComparer<T>();

    if (comparer.Compare(value, max) > 0)
        return max;

    if (comparer.Compare(value, min) < 0)
        return min;

    return value;
}
publicstatict?夹紧(此T值,T最小值,T最大值)
其中T:struct
{
var comparer=新的NullableComparer();
如果(比较器比较(值,最大值)>0)
返回最大值;
if(比较器比较(值,最小值)<0)
返回最小值;
返回值;
}
方便保存在助手库中


希望有帮助

我不知道我为什么不直接做(value==null)?值:value.Clamp(099999);首先。我想我只是想强迫夹钳自动完成。但是是的,因为它是钳制的,所以不使它为空实际上更有意义。