m-y*_*m-y 10 c# generics nullable icomparable
我正在尝试创建一个简单的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);
}
}
Run Code Online (Sandbox Code Playgroud)
Iña*_*oro 14
正如@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);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您将使用此类:
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;
}
Run Code Online (Sandbox Code Playgroud)
方便您在助手库中保存.
希望能帮助到你!
记住,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...
}
Run Code Online (Sandbox Code Playgroud)
当然,如果您计划使用可空类型,则必须定义如何限制null
值...
如果您实际上不需要钳制null
值,那么首先在属性getter中检查null可能更简单:
public Int32? Zip
{
...
set
{
_zip = value == null ? value : value.Value.Clamp<Int32>(0,99999);
}
Run Code Online (Sandbox Code Playgroud)
或者更好的是,让它成为执行额外重载的一部分Clamp
......