Monday, February 9, 2009

Sorting with Objects on multiple fields - C#

This article demonstrates how to apply sorting on objects. It is useful when you need to apply sorting on objects e.g. Object Person(Name, Age) and you want to apply sorting on Person->Name, or you may wish to apply sorting on multiple fields i.e. Person->name DESC + person->age DESC.

It is very useful when you want to apply multiple column sorting on GridViews with ObjectDataSource.


Using Reflection its very easy to sort objects. I had used Lists to sort objects and ObjectComparer class is inherited from IComparer

ObjectComparer supports Single as well as Multiple sorting.

//
//
//Test.cs
//Created an array of Person object, for which i wish to apply sorting

Person[] personArray = new Person[] {
new Person("Ritesh", 26),
new Person("Arpan", 20),
new Person("Arpan", 23),
new Person("Hiren", 22),
new Person("Ankit", 22),
new Person("Dhaval", 23),
new Person("Gaurav", 25)
};

//Sort array on field Name in Ascending Order
Array.Sort(personArray, new ObjectComparer<Person>("Name"));

//Sort array on field Name Decending and Age Ascending
Array.Sort(personArray, new ObjectComparer<Person>("Name DESC, Age ASC",true));

ObjectComparer.cs


[Serializable]
public class ObjectComparer<ComparableObject> : IComparer<ComparableObject>
{
#region Constructor
public ObjectComparer()
{
}

public ObjectComparer(string p_propertyName)
{
//We must have a property name for this comparer to work
this.PropertyName = p_propertyName;
}

public ObjectComparer(string p_propertyName, bool p_MultiColumn)
{
//We must have a property name for this comparer to work
this.PropertyName = p_propertyName;
this.MultiColumn = p_MultiColumn;
}
#endregion

#region Property
private bool _MultiColumn;
public bool MultiColumn
{
get { return _MultiColumn; }
set { _MultiColumn = value; }
}

private string _propertyName;
public string PropertyName
{
get { return _propertyName; }
set { _propertyName = value; }
}
#endregion


#region IComparer<ComparableObject> Members
/// <summary>
/// This comparer is used to sort the generic comparer
/// The constructor sets the PropertyName that is used
/// by reflection to access that property in the object to
/// object compare.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public int Compare(ComparableObject x, ComparableObject y)
{
Type t = x.GetType();
if (_MultiColumn) // Multi Column Sorting
{
string[] sortExpressions = _propertyName.Trim().Split(',');
for (int i = 0; i < sortExpressions.Length; i++)
{
string fieldName, direction = "ASC";
if (sortExpressions[i].Trim().EndsWith(" DESC"))
{fieldName = sortExpressions[i].Replace(" DESC", "").Trim();
direction = "DESC";
}
else
{
fieldName = sortExpressions[i].Replace(" ASC", "").Trim();
}

//Get property by name
PropertyInfo val = t.GetProperty(fieldName);
if (val != null)
{
//Compare values, using IComparable interface of the property's type
int iResult = Comparer.DefaultInvariant.Compare(val.GetValue(x, null), val.GetValue(y, null));
if (iResult != 0)
{
//Return if not equal
if (direction == "DESC")
{
//Invert order
return -iResult;
}
else
{
return iResult;
}
}
}
else
{
throw new Exception(fieldName + " is not a valid property to sort on. It doesn't exist in the Class.");
}
}
//Objects have the same sort order
return 0;
}
else
{
PropertyInfo val = t.GetProperty(this.PropertyName);
if (val != null)
{
return Comparer.DefaultInvariant.Compare(val.GetValue(x, null), val.GetValue(y, null));
}
else
{
throw new Exception(this.PropertyName + " is not a valid property to sort on. It doesn't exist in the Class.");
}
}
}
#endregion

}


2 comments:

achilleraczkowski said...

Casinos That Accept PayPal - DrMCD
How to 여수 출장안마 withdraw your money from online 전라북도 출장마사지 casino 군포 출장샵 sites? · Deposits 광주광역 출장샵 · Withdrawal Methods · Mobile Payments · Deposit 양주 출장안마 Methods. · Withdrawal Methods.

halseymaas said...

Just be sure to|make certain to|remember to} set a budget for your self and stick with it so that you don’t end 포커 up spending more than find a way to|you probably can} afford to lose. Legislation to legalize Massachusetts sports betting handed in August 2022, however just isn't anticipated to fully launch till early 2023. Betting on in-state collegiate sports, each sport outcomes and participant props, will be prohibited. Betting on the end result} of an in-state faculty sport will only be allowed if that group is taking part in} in a match comprising four or more groups.