如何对具有动态对象的列表进行排序 [英] How to sort a list having dynamic object
问题描述
问题背景:我有一个
BindingList<T>
的动态对象。这些对象属于在运行时创建的某种类。此类可以包含1个或2个或3个或更多属性。每次创建此类时,这些属性的名称也可能不同。
例如
of dynamic objects. These objects are of some type of class which is created at runtime. This class can have 1 or 2 or 3 or more properties. Names of these properties can also be different everytime when this class is created.
e.g.
Class Data
{
Property Value1;
Property Value2;
Property Value3;
..
...
}
下次此课程可以
Next time this class can be
Class Data
{
Property Value1;
Property Value2;
}
问题是:根据某些参数,我可以从用户那里获得一个值'值1。然后我想在属性''Value1''的值上对这个动态对象列表进行排序。
Issue is: Based on some parameter I can get a value from user ''Value1''. Then I want to sort this list of dynamic objects on value of property ''Value1''.
推荐答案
你需要实现一个Comparer [ ^ ],并将其传递给列表.Sort [ ^ ]方法。
但是由于你有动态对象,你需要使用反射来获取值。使用这个 [ ^ ]方法:
You need to implement a Comparer[^], and pass it to the List.Sort[^] method.
But since you have dynamic objects, you need to use reflection to get the values. Use this[^] approach:
public class DynamicSerializableComparer : IComparer<object>
{
string _property;
public DynamicSerializableComparer(string property)
{
_property = property;
}
public int Compare(object stringA, object stringB)
{
string valueA = stringA.GetType().GetProperty(_property).GetValue();
string valueB = stringB.GetType().GetProperty(_property).GetValue();
return String.Compare(valueA, valueB);
}
}
当然,如果您拥有的属性不是字符串或不能与字符串相比,您应该更改相应的最后陈述。
[更新:一些改进和样本]
正如我所提到的,你不能使用 OrderBy
,因为你没有在lambda表达式中指定的属性。
Of course, if the property you have is not string or not comparable as string, you should change the last statement accordingly.
[Update: some improvements, and a sample]
As I mentioned, you can''t use OrderBy
, since there is no property you can specify in the lambda expression.
public class DynamicSerializableComparer : IComparer<object>
{
string _property;
public DynamicSerializableComparer(string property)
{
_property = property;
}
public int Compare(object stringA, object stringB)
{
string valueA = (string)stringA.GetType().GetProperty(_property).GetValue(stringA, null);
string valueB = (string)stringB.GetType().GetProperty(_property).GetValue(stringB, null);
return String.Compare(valueA, valueB);
}
}
void Main()
{
var a1 = new { id = 1, name="Peter", email="a@x.com"};
var a2 = new { id = 2, name="John", address="USA"};
var a3 = new { id = 3, name="Robert", address="France"};
var a4 = new { id = 4, name="Albert", position="Boss"};
var a = new List<object> {a1, a2, a3, a4};
a.Sort(new DynamicSerializableComparer("name"));
a.Dump();
}
此示例将直接在 LinqPad [ ^ ](如果你不喜欢,我建议你下载它如果你开发了linq的东西,它是必须的......,但你可以编写一个简单的转储器或检查VS中的排序列表。如您所见,甚至没有定义类,所有对象都是内联的。如果将构造函数参数更改为在所有对象中不常见的属性,则无法工作 - 在这种情况下,您必须决定并向比较器添加逻辑,以便比较不存在的属性。但您可以使用此示例来实现满足您需求的比较器。
This sample will run directly in LinqPad[^] (I suggest you download it if you don''t have it already, it is a must if you develop linq stuff...), but you can write a simple dumper or inspect the sorted list in VS. As you can see, there is not even a class defined, all objects are inline. Won''t work if you change the constructor parameter to a property that''s not common in all objects - in such case you have to decide and add logic to the comparer how to compare nonexistent properties. But you can use this sample to implement a comparer for your needs.
这篇关于如何对具有动态对象的列表进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!