我需要根据运行时确定的标准对这些集合进行排序。
我使用了this文章中的代码来执行排序--我的代码最初使用的是动态类。
然后我遇到了在WCF上序列化的问题,所以我转而使用SerializableDynamicObject,现在排序代码在行上中断了:
PropertyInfo pi = type.GetProperty(prop);错误是SerializableDynamicObject没有名为"Name“的属性--其中"Name”是prop的值。
我想最简单的做法是找到另一种方法来序列化排序算法所使用的动态类型。任何在这个方向上的指针都将不胜感激!
我看过this示例,但得到了错误消息:
The constructor with parameters (SerializationInfo, StreamingContext) is not found in ISerializable type发布于 2012-06-26 20:10:26
下面是一些使用FastMember实现的代码,它既适用于基于反射的对象,也适用于dynamic-based对象(取决于您传递给TypeAccessor.Create的内容)。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using FastMember;
namespace ConsoleApplication6
{
class Program
{
static void Main()
{
var list = new List<dynamic>();
dynamic obj = new ExpandoObject();
obj.Foo = 123;
obj.Bar = "xyz";
list.Add(obj);
obj = new ExpandoObject();
obj.Foo = 456;
obj.Bar = "def";
list.Add(obj);
obj = new ExpandoObject();
obj.Foo = 789;
obj.Bar = "abc";
list.Add(obj);
var accessor = TypeAccessor.Create(
typeof(IDynamicMetaObjectProvider));
string propName = "Bar";
list.Sort((x,y) => Comparer.Default.Compare(
accessor[x, propName], accessor[y,propName]));
foreach(var item in list) {
Console.WriteLine(item.Bar);
}
}
}
}值得一提的是,对于基于反射的类型,这不是使用每个项目的反射;所有这些都是通过元编程优化的。
发布于 2012-06-26 22:05:45
Marc Gravell的回答给了我完成这个任务的答案-我需要实现一个可以处理多个排序标准的排序器,直到运行时才知道。我接受Marc的回答,但如果有人把这篇文章贴出来,可能也会觉得很有用。
可能有一种更优雅的方式来实现这一点,如果是这样的话,请让我知道,我会更新答案。
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"}https://stackoverflow.com/questions/11206631
复制相似问题