Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Int32? with IComparable

Tags:

c#

.net

I have a DataGridView whose datasource is a BindingList. MyObj has a few nullable properties (like int? and DateTime?) I want to implement sorting to my binding list, so the DataGridView can sort the column when the user clicks on the column header.

After some digging around, I found and followed the answer of this question (DataGridView Column sorting with Business Objects).

I can't get that solution to work for Nullable types because they don't implement IComparable. Even for classes that implement IComparable like String, ApplySortCore(...) fails when the String has a null value.

Is there a solution for this? Or do I have to implement a wrapper class for "Int32?" ?

eg

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
}
like image 971
David Avatar asked Aug 11 '09 21:08

David


People also ask

What is IComparable?

Compares the current instance with another object of the same type and returns an integer that indicates whether the current instance precedes, follows, or occurs in the same position in the sort order as the other object.

What is IComparable and IComparer?

IComparer compares two objects that it's given. IComparable is implemented by the object that is being compared, for the purpose of comparing with another one of itself. It is a good idea to implement IComparable for sorting objects.

How does IComparable work C#?

C# IComparable interfaceThe IComparable interface defines a generalized type-specific comparison method that a value type or class implements to order or sort its instances. The IComparable is implemented by types whose values can be ordered or sorted. The interface requires the CompareTo method to be implemented.

Does string implement IComparable?

All numeric types (such as Int32 and Double) implement IComparable, as do String, Char, and DateTime.


1 Answers

Nullable<int> may not implement IComparable, but surely int does. And Nullable<T> always boxes to T (for instance when you cast to an interface, such as IComparable, which is a boxing conversion). So comparing/sorting on nullable properties should not be a problem.

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

So, the check in the sample at the top does not work right. Try this:

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

One more addition: if you want null values to work as well (both string and nullable types), you could try this re-implementation of 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));
}

There's no need to look for IComparable directly, just let the sorting methods themselves sort it out.

like image 87
Ruben Avatar answered Oct 04 '22 08:10

Ruben