INT32?与IComparable

时间:2009-08-11 21:21:25

标签: c# .net

我有一个DataGridView,其数据源是BindingList。 MyObj有一些可以为空的属性(比如int?和DateTime?)我想实现对绑定列表的排序,因此当用户点击列标题时,DataGridView可以对列进行排序。

经过一番挖掘后,我找到了并回答了这个问题的答案(DataGridView Column sorting with Business Objects)。

我无法让这个解决方案适用于Nullable类型,因为它们没有实现IComparable。即使对于像String这样实现IComparable的类,当String具有空值时,ApplySortCore(...)也会失败。

有解决方案吗?或者我是否必须为“Int32”实现包装类? ?

例如

public class Int32Comparable : IComparable
{
    public int? Value { get; set; }

    #region IComparable<int?> Members

    public int CompareTo(object other)
    {
        // TODO: Implement logic here
        return -1;
    }

    #endregion
}

2 个答案:

答案 0 :(得分:11)

Nullable<int>可能无法实现IComparable,但肯定会int。并且Nullable<T>始终为T框(例如,当您转换为界面时,例如IComparable,这是一个装箱转换)。因此,对可空属性进行比较/排序应该不是问题。

int? value = 1;
IComparable comparable = value; // works; even implicitly

因此,顶部样本中的检查无法正常工作。试试这个:

Type interfaceType = prop.PropertyType.GetInterface("IComparable");
// Interface not found on the property's type. Maybe the property was nullable?
// For that to happen, it must be value type.
if (interfaceType == null && prop.PropertyType.IsValueType)
{
    Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
    // Nullable.GetUnderlyingType only returns a non-null value if the
    // supplied type was indeed a nullable type.
    if (underlyingType != null)
        interfaceType = underlyingType.GetInterface("IComparable");
}
if (interfaceType != null)
   // rest of sample

还有一个补充:如果你想要空值(字符串和可空类型),你可以尝试重新实现SortCore(...)

protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
    IEnumerable<MyClass> query = base.Items;
    if (direction == ListSortDirection.Ascending)
        query = query.OrderBy( i => prop.GetValue(i) );
    else
        query = query.OrderByDescending( i => prop.GetValue(i) );
    int newIndex = 0;
    foreach (MyClass item in query)
    {
        this.Items[newIndex] = item;
        newIndex++;
    }
    this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}

无需直接查找IComparable,只需让排序方法自行对其进行排序。

答案 1 :(得分:4)

比较你的可空类型时,你可以做这样的事情......

Int32? val1 = 30;
Int32 val2 = 50;

Int32 result = (val1 as IComparable).CompareTo(val2);