0

我有一个具有 18 个属性的对象(称为 MyReading)。我将此对象的实例添加到列表

例如:

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) 的 (Comparison Delegate) 和一个字符串,它指示要排序的属性。

这怎么可能?

4

2 回答 2

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])以很少的成本调用。

于 2013-11-15T11:06:03.760 回答
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”一样。

于 2013-11-15T11:17:58.307 回答