首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用SerializableDynamicObject进行动态排序

使用SerializableDynamicObject进行动态排序
EN

Stack Overflow用户
提问于 2012-06-26 19:46:04
回答 2查看 701关注 0票数 1

我需要根据运行时确定的标准对这些集合进行排序。

我使用了this文章中的代码来执行排序--我的代码最初使用的是动态类。

然后我遇到了在WCF上序列化的问题,所以我转而使用SerializableDynamicObject,现在排序代码在行上中断了:

代码语言:javascript
复制
  PropertyInfo pi = type.GetProperty(prop);

错误是SerializableDynamicObject没有名为"Name“的属性--其中"Name”是prop的值。

我想最简单的做法是找到另一种方法来序列化排序算法所使用的动态类型。任何在这个方向上的指针都将不胜感激!

我看过this示例,但得到了错误消息:

代码语言:javascript
复制
The constructor with parameters (SerializationInfo, StreamingContext) is not found in ISerializable type
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-06-26 20:10:26

下面是一些使用FastMember实现的代码,它既适用于基于反射的对象,也适用于dynamic-based对象(取决于您传递给TypeAccessor.Create的内容)。

代码语言:javascript
复制
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);
            }
        }
    }
}

值得一提的是,对于基于反射的类型,这不是使用每个项目的反射;所有这些都是通过元编程优化的。

票数 2
EN

Stack Overflow用户

发布于 2012-06-26 22:05:45

Marc Gravell的回答给了我完成这个任务的答案-我需要实现一个可以处理多个排序标准的排序器,直到运行时才知道。我接受Marc的回答,但如果有人把这篇文章贴出来,可能也会觉得很有用。

可能有一种更优雅的方式来实现这一点,如果是这样的话,请让我知道,我会更新答案。

代码语言:javascript
复制
 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;
    }
}

用法:

代码语言:javascript
复制
var sorter = new SerializableDynamicObjectComparer(sortCriteria);

var sortableData = reportData.ToList();
sortableData.Sort(sorter.Compare);

其中sortCriteria是字符串数组,例如

代码语言:javascript
复制
 new {"Name.DESC", "Age.ASC", "Count"}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11206631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档