C# 使用SerializableDynamicObject进行动态排序
我需要根据运行时确定的标准对这些集合进行排序 我使用文章中的代码来执行排序-最初我的代码使用动态类 然后我遇到了通过WCF进行序列化的问题,所以我切换到使用a,现在排序代码在行中中断:C# 使用SerializableDynamicObject进行动态排序,c#,xml,wcf,serialization,dynamic,C#,Xml,Wcf,Serialization,Dynamic,我需要根据运行时确定的标准对这些集合进行排序 我使用文章中的代码来执行排序-最初我的代码使用动态类 然后我遇到了通过WCF进行序列化的问题,所以我切换到使用a,现在排序代码在行中中断: PropertyInfo pi = type.GetProperty(prop); 错误是SerializableDynamicObject没有名为“Name”的属性,其中“Name”是prop的值 我想最简单的方法是找到一种序列化排序算法使用的动态类型的替代方法。任何指向这个方向的指示都将不胜感激 我已经
PropertyInfo pi = type.GetProperty(prop);
错误是SerializableDynamicObject没有名为“Name”的属性,其中“Name”是prop的值
我想最简单的方法是找到一种序列化排序算法使用的动态类型的替代方法。任何指向这个方向的指示都将不胜感激
我已经看过这个示例,但我得到了错误消息:
The constructor with parameters (SerializationInfo, StreamingContext) is not found in ISerializable type
下面是一些用于此的代码,它适用于基于反射和基于的动态对象(取决于传递给TypeAccessor.Create的内容)
使用系统;
使用系统集合;
使用System.Collections.Generic;
运用系统动力学;
使用FastMember;
命名空间控制台应用程序6
{
班级计划
{
静态void Main()
{
var list=新列表();
动态对象=新的ExpandooObject();
obj.Foo=123;
obj.Bar=“xyz”;
列表。添加(obj);
obj=新的ExpandooObject();
obj.Foo=456;
obj.Bar=“def”;
列表。添加(obj);
obj=新的ExpandooObject();
obj.Foo=789;
obj.Bar=“abc”;
列表。添加(obj);
var accessor=TypeAccessor.Create(
typeof(IDynamicMetaObjectProvider));
字符串propName=“Bar”;
list.Sort((x,y)=>Comparer.Default.Compare(
访问器[x,propName],访问器[y,propName]);
foreach(列表中的变量项){
控制台写入线(条);
}
}
}
}
可能值得注意的是,对于基于反射的类型,它不会在每个项目的基础上使用反射;所有这些都是通过元编程优化的。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;
}
}
其中sortCriteria是字符串数组,例如
new {"Name.DESC", "Age.ASC", "Count"}
太棒了-谢谢你的Marc和你另一篇帖子上的有用评论-否则我会花很多时间试图走错方向。我最关心的是你给Touper打电话的次数。小心!我会先在bool
中测试这一点。事实上,在比较(x,y)
中,您几乎不想做任何事情,这将被调用。改为在构造函数中执行。是的-非常好的一点将更正和更新-再次感谢!
var sorter = new SerializableDynamicObjectComparer(sortCriteria);
var sortableData = reportData.ToList();
sortableData.Sort(sorter.Compare);
new {"Name.DESC", "Age.ASC", "Count"}