[英]Generic Compare throws “At least one object must implement IComparable.”
[英]Nullable generic type used with IComparable. Is it possible?
我正在尝试创建一个简单的Clamp(这样我就可以绑定任何类似的值...主要用于数字类型,如int,double等)
问题是如果我执行以下操作我得到一个错误,但根据MSDN IComparable的CompareTo应该能够处理空值。
Quote:“根据定义,任何对象都比较大于null,两个空引用比较相等。”
public static T Clamp<T>(this T value, T min, T max)
where T : IComparable<T>
{
if (value.CompareTo(max) > 0)
return max;
if (value.CompareTo(min) < 0)
return min;
return value;
}
private Int32? _zip;
public Int32? Zip
{
get
{
return _zip;
}
set
{
_zip = value.Clamp<Int32?>(0, 99999);
}
}
正如@LBushkin Nullable <T>或T? 没有实现IComparable接口。 给定的解决方案是可以的,但是我更喜欢在单一责任原则之下在专门的类中使用可空的比较逻辑,并且还可以用于比较任何Nullable类型。
例如,您可以创建一个通用的Nullable类型比较器类,如下所示:
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;
}
方便您在助手库中保存。
希望能帮助到你!
还记得, Int32?
是Nullable<Int32>
的简写。 由于Nullable<T>
没有实现IComparable<T>
,因此您的代码将无法编译。
但是,您可以重载该方法:
public static T? Clamp<T>(this T? value, T? min, T? max)
where T : struct, IComparable<T>
{
// your logic...
}
当然,如果您计划使用可空类型,则必须定义如何限制null
值...
如果您实际上不需要钳制null
值,那么首先在属性getter中检查null可能更简单:
public Int32? Zip
{
...
set
{
_zip = value == null ? value : value.Value.Clamp<Int32>(0,99999);
}
或者更好的是,让它成为Clamp
额外重载实现的一部分......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.