Marc Gravell的回答給了我完成這個答案 - 我需要實現一個可以處理多種排序條件的分揀器,直到運行時才能知道。我接受馬克的回答,但發佈這個作爲人可能會發現它也很有用。
有可能是一個更優雅的方式來實現這一點,如果是這樣,請讓我知道,我會更新答案。
public class SerializableDynamicObjectComparer: IComparer
{
private readonly List<KeyValuePair<string, bool>> sortCriteria = new List<KeyValuePair<string, bool>>();
private readonly TypeAccessor accessor;
public SerializableDynamicObjectComparer(IEnumerable<string> criteria)
{
foreach (var criterium in criteria)
{
string[] sortCriterium = criterium.Split('.');
this.sortCriteria.Add(new KeyValuePair<string, bool>(sortCriterium[0],
sortCriterium.Length == 0
? sortCriterium[1].ToUpper() == "ASC"
: false));
}
this.accessor = TypeAccessor.Create(typeof (IDynamicMetaObjectProvider));
}
public int Compare(object x, object y)
{
for(int i=0; i< this.sortCriteria.Count; i++)
{
string fieldName = this.sortCriteria[i].Key;
bool isAscending = this.sortCriteria[i].Value;
int result = Comparer.Default.Compare(this.accessor[x, fieldName], this.accessor[y, fieldName]);
if(result != 0)
{
//If we are sorting DESC, then return the -ve of the default Compare result
return isAscending ? result : -result;
}
}
//if we get here, then objects are equal on all sort criteria.
return 0;
}
}
用法:
var sorter = new SerializableDynamicObjectComparer(sortCriteria);
var sortableData = reportData.ToList();
sortableData.Sort(sorter.Compare);
其中SortCriteria是一個字符串數組例如
new {"Name.DESC", "Age.ASC", "Count"}
輝煌 - 感謝Marc,以及對您其他文章的有用評論 - 我會花費很多時間試圖走錯方向。 – BonyT