问题
I'm trying to write a generic object comparer for sorting, but I have noticed it does not handle the instance where one of the values it's comparing is null. When an object is null, I want it to treat it the same as the empty string. I've tried setting the null values to String.Empty but then I get an error of "Object must be of type String" when calling CompareTo() on it.
public int Compare(T x, T y)
{
PropertyInfo propertyInfo = typeof(T).GetProperty(sortExpression);
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null);
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null);
if (obj1 == null) obj1 = String.Empty; // This doesn't work!
if (obj2 == null) obj2 = String.Empty; // This doesn't work!
if (SortDirection == SortDirection.Ascending)
return obj1.CompareTo(obj2);
else
return obj2.CompareTo(obj1);
}
I'm pretty stuck with this now! Any help would be appreciated.
回答1:
You cannot treat your T
as an empty string unless your T was effectively constrained to being a string. What you should do is have a plan for comparing nulls. Such as
if (obj1 == null && obj2 == null)
return 0;
else if (obj1 == null)
return -1;
else if (obj2 == null)
return 1;
else
return obj1.CompareTo(obj2);
回答2:
if (SortDirection == SortDirection.Ascending)
return Comparer<T>.Default.Compare(obj1, obj2);
else
return Comparer<T>.Default.Compare(obj2, obj1);
回答3:
Since T
is a generic type, you cannot assign it a String
value; you can only assign it a value of type T
. If you are only going to use this to compare strings, use String
instead of T
. Otherwise, add null checking and decide where in order null
should fall.
回答4:
IComparable obj1 = (IComparable)propertyInfo.GetValue(x, null) ?? "";
IComparable obj2 = (IComparable)propertyInfo.GetValue(y, null) ?? "";
This basically means that obj1 will now be the value of propertyInfo.GetValue(x, null) or, if that happens to be null, obj1 will be "".
Or if the problem is that the GetValue crashes on null you could do something like:
IComparable obj1 = "";
try { obj1 = (IComparable)propertyInfo.GetValue(x, null); } catch {}
来源:https://stackoverflow.com/questions/4852432/how-can-i-make-my-generic-comparer-icomparer-handle-nulls