我有一个具有18个属性的Object(Called MyReading)。 我将此Object的实例添加到List
例如:
List<MyReading> MyReadingsL = new List<MyReading>();
MyReading O1 = new MyReading();
O1._DateTime = "10";
O1._Value1 = "Hello1";
O1._Value2 = "Hello2";
O1._Value3 = "Hello3";
O1._Value4 = "Hello4";
....etc
MyReadingsL.Add(O1);
我需要按18个属性中的任何一个对读数列表进行排序。 (用户决定哪些) 我知道我必须为列表的Sort()方法编写一个委托,在代码中指定我自己的比较逻辑。
例如。 MyReadingsL.Sort(TheDelegate);
问题是,我不想为每个可以可能排序的属性编写18个代理。 也许一个委托,一个(比较代表)接受(MyReading x,MyReading y)和一个字符串,表示要排序的属性。
这怎么可能?
答案 0 :(得分:3)
很简单。 Linq已经给你了:
MyReadingsL.OrderBy(r => r._Value1);
MyReadingsL.OrderBy(r => r._Value2);
...
MyReadingsL.OrderBy(r => r._Valuen);
...
如果要定义以相同方式调用的外部函数,则您的签名应如下所示:
public IEnumerable<MyReading> GetSortedList(Func<MyReading, string> property) { }
要从字符串转换为属性,您可以定义静态数据成员。
public static IDictionary<string, Func<MyReading, string>> Properties =
typeof(MyReading).GetProperties().ToDictionary(p => prop.Name, p => new Func<MyReading, string>(r => p.GetValue(r)));
这个静态成员为您提供了类中所有属性的字典,由其标识字符串键入,并允许您访问可以执行所需Linq操作的委托。
然后,给定一个标识属性的字符串s
,您可以以非常低的成本调用MyReadingsL.OrderBy(Properties[s])
。
答案 1 :(得分:1)
你可以通过linq实现这一目标。你需要做的是传递你想要排序的字符串/属性,然后使用orderby
。
一般例子:
// Create 10 objects with 2 properties
var num_and_name_list =
from num in Enumerable.Range(1,10)
select new { val=num, name=(""+num+"oeu")};
// Here i'll sort them by the name property.
var sorted_by_name_list =
from some_object in num_and_name_list
orderby some_object.name descending
select some_object;
结果将如下所示
所以,你只需要看看你如何/在哪里通过你的财产进行排序。
如果您需要从字符串中获取属性,您可以执行以下操作:
// Create 10 objects with 3 properties
var num_and_name_list =
from num in Enumerable.Range(1, 10)
select new ExtraStringDataPoint ( num, num*2, ("" + num + "oeu"));
// Hunting your property starts
Type myType = num_and_name_list.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());
PropertyInfo order_on_this = null;
foreach (PropertyInfo prop in props)
{
order_on_this = typeof(ExtraStringDataPoint).GetProperty("Y");
}
// Here i'll sort them by the name property.
var sorted_by_name_list =
from some_object in num_and_name_list
orderby order_on_this descending
select some_object;
我的ExtraStringDataPoint
看起来像是:
public class ExtraStringDataPoint : IDataPoint
{
public ExtraStringDataPoint(double x, double y, string s)
{
X = x;
Y = y;
Extra = s;
}
public double X { get; set; }
public double Y { get; set; }
public string Extra { get; set; }
public override string ToString()
{
return X +" , " + Y + " , " + Extra;
}
}
在您的情况下,您可以将所需的变量作为字符串传递,就像我使用“Y”一样。