KeyedCollection - How To Sort???
-
Thursday, February 22, 2007 7:18 PM
I have a custom collection created that derives from KeyedCollection. Everything works great exept I want to be able to sort based on a property in one of the objects in the collection. How does that work as I can't seem to find any examples on sorting a KeyedCollection class?
Below is my sample code
public abstract class BusinessKeyedCollectionBase<K,T> : KeyedCollection<K,T> where T : IBusinessKeyedObject<K>
{
// This parameterless constructor delegates to the base class
// constructor that specifies a dictionary threshold. A
// threshold of 0 means the internal Dictionary is created
// the first time an object is added.public BusinessKeyedCollectionBase()
: base(null, 0)
{ }protected override K GetKeyForItem(T t)
{
return t.Key;
}public void Sort(string sortExpression)
{
}
}public interface IBusinessKeyedObject<K>
{
// Property signatures:
K Key
{
get;
set;
}}
All Replies
-
Thursday, February 22, 2007 11:57 PM
You can sort the underlying collection by accessing the Items property. Cast the IList interface to a concrete List<T> and you can access the Sort() method.
You will need to define a Comparer in order to implement sorting by property. I have worked up a quick example that you can improve in.
class BusinessKeyedCollection<K,T> : KeyedCollection<K,T> where T:IBusinessObject<K>
{
protected override int GetKeyForItem(T item)
{
return item.Key;
}
public void Sort(string property)
{
List<T> list = base.Items as List<T>;
if (list != null)
{
if (String.IsNullOrEmpty(property))
{
property = "Key";
}
ObjectComparer<T> comparer = new ObjectComparer<T>(property);
list.Sort(comparer);
}
}
}
class ObjectComparer<T> : Comparer<T>
{
PropertyInfo m_propertyInfo;
public ObjectComparer(PropertyInfo pi)
{
m_propertyInfo = pi;
}
public ObjectComparer(string property)
{
m_propertyInfo = typeof(T).GetProperty(property);
}
public override int Compare(T x, T y)
{
Debug.Assert(m_propertyInfo != null);
if (x == null && y==null)
{
return 0;
}
else if (x == null)
{
return -1;
}
IComparable xComparer = m_propertyInfo.GetValue(x, null) as IComparable;
object yValue = m_propertyInfo.GetValue(y, null);
if (xComparer == null)
{
throw new ArgumentOutOfRangeException("Object does not support IComparable interface");
}
return xComparer.CompareTo(yValue);
}
}- Marked As Answer by M_Over Wednesday, August 20, 2008 5:18 PM
-
Friday, March 02, 2007 2:56 PMThanks for the help and the for the code.
-
Wednesday, June 25, 2008 11:48 PM
I've been interested in a SortedKeyedCollection for a while, and finally got down to writing my own. I write a lot of API code for other teams in my company, so as per Microsoft guidelines, using SortedList and SortedDictionary isn't really an option; and I would rather have the collection sorted automatically, rather than having to call the Sort() method as you have. I've put up a blog entry about it, but here's my code in brief:using System.Collections.Generic; using System.Collections.ObjectModel; public abstract class SortedKeyedCollection<TKey, TItem> : KeyedCollection<TKey, TItem> { protected virtual IComparer<TKey> KeyComparer { get { return Comparer<TKey>.Default; } } protected override void InsertItem(int index, TItem item) { int insertIndex = index; for (int i = 0; i < Count; i++) { TItem retrievedItem = this[i]; if (KeyComparer.Compare(GetKeyForItem(item), GetKeyForItem(retrievedItem)) < 0) { insertIndex = i; break; } } base.InsertItem(insertIndex, item); } }
It can be easily extended, so if you have some weird key, you just need to provide your own comparer to handle the sorting.
- Edited by David Keaveny Wednesday, June 25, 2008 11:51 PM Fixed typo

