我正在尝试创建一个简单的Clamp(这样我就可以绑定任何类似的值...主要用于数字类型,如int,double等)。
问题是,如果我执行以下操作,则会收到错误,但according to 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);
}
}
答案 0 :(得分:13)
如@LBushkin Nullable所说&lt; T>还是T?没有实现IComparable接口。给定的解决方案是可以的,但是我更喜欢在Single Responsibility Principle之后在专门的类中使用可空的比较逻辑,并且还可以用于比较任何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;
}
方便您在助手库中保存。
希望它有所帮助!
答案 1 :(得分:7)
请记住,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
...