Implementing Icomparable Interface for generic class
-
28-04-2021 - |
سؤال
I am not able to find out as to how to implement the IComparable
interface method CompareTo
for a generic class.
I have a class called BindingProperty<T>
which is used to create a List<BindingProperty<intOrString>>
to bind to a DataGrid
. The problem is that the I can not perform the Sort operation as the IComparable
interface is not implemented by this BindingProperty<T>
class. The result of comparison would depend on a data member 'Value' of the the BindingProperty<T>
class where 'Value' is of Type T. When I click on the column header of the DataGrid, I get an exception that CompareTo()
method is not implemented.
I would need help to implement this interface. Should I be using IComparable<T>
? If yes, how do I do it?
Thanks in advance Shakti
المحلول
Set up a generic type constraint on T.
public class BindingProperty<T> : IComparable where T : IComparable
{
public T Value {get; set;}
public int CompareTo(object obj)
{
if (obj == null) return 1;
var other = obj as BindingProperty<T>;
if (other != null)
return Value.CompareTo(other.Value);
else
throw new ArgumentException("Object is not a BindingProperty<T>");
}
}
Edit:
Alternative solution to handle if value does not implement IComparable
. This will support all types, just wont sort if they do not implement IComparable
.
public class BindingProperty<T> : IComparable
{
public T Value {get; set;}
public int CompareTo(object obj)
{
if (obj == null) return 1;
var other = obj as BindingProperty<T>;
if (other != null)
{
var other2 = other as IComparable;
if(other2 != null)
return other2.CompareTo(Value);
else
return 1; //Does not implement IComparable, always return 1
}
else
throw new ArgumentException("Object is not a BindingProperty<T>");
}
}
نصائح أخرى
If the Type is a custom class, then your custom class needs to be IComparable.
e.g.
List<FooClass>
, then FooClass
needs to inherit/implement IComparable
.
You can use a generic constraint to require that T
implements IComparable<T>
. You can then compare two BindingProperty<T>
instance by comparing their Value
members. It is not clear to me if you need your class to implement IComparable
or IComparable<T>
but implemeting both is not much extra work.
class BindingProperty<T>
: IComparable<BindingProperty<T>>, IComparable where T : IComparable<T> {
public T Value { get; set; }
public Int32 CompareTo(BindingProperty<T> other) {
return Value.CompareTo(other.Value);
}
public Int32 CompareTo(Object other) {
if (other == null)
return 1;
var otherBindingProperty = other as BindingProperty<T>;
if (otherBindingProperty == null)
throw new ArgumentException();
return CompareTo(otherBindingProperty);
}
}