对多种数据类型的对象列表进行排序

时间:2015-04-17 15:36:18

标签: c# list class sorting reflection

我的代码中有这个类

class Stock
{
    public DateTime Date;
    public string Day;
    public double Open, Close, Diff;
    public int Volume;

    public Stock(double open, double close, double diff, int volume, string day, DateTime date)
    {
        this.Open = open;
        this.Close = close;
        this.Diff = diff;
        this.Volume = volume;
        this.Day = day;
        this.Date = date;
    }
}

在另一个类中我想创建一个冒泡排序,它会对传递给它的股票列表(List<Stocks>)进行排序,我遇到了多个问题,主要问题是数据类型,不容易比较两个值可以是stringintdoubleDateTime。我用一个使用TryParse检查有效数据类型的方法来完成它,但我正在寻找一个很好的干净解决方案,这是我到目前为止的尝试

public void BubblesortBy(int sortBy, List<Stock> Stocks)
{

    Type objType = typeof(Stock);
    FieldInfo[] fields = objType.GetFields();

    Stock temp = null;
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < Stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < Stocks.Count - 1; j++)
        {
            if (Compare(fields[sortBy - 1].FieldType.ToString(), fields[sortBy].GetValue(Stocks[j]), fields[sortBy].GetValue(Stocks[j+1])))
            {
                temp = Stocks[sortBy + 1];
                Stocks[sortBy + 1] = Stocks[sortBy];
                Stocks[sortBy] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak) { break; /*early escape*/ }
    }
}

传递给它的int决定了是否要排序,这就是我使用反射的原因所以变量可以通过数字访问。

  1. 日期
  2. 打开
  3. 关闭
  4. 差分

2 个答案:

答案 0 :(得分:1)

为什么要自己实施排序?查看IComparable

编辑:

一种不错且安全的方式来传递字段以便在没有反复意见的情况下排序到方法中,将是:

BubblesortBy(x => x.FieldName, stockes);

public void BubblesortBy<T>(Func<Product, T> sortBy, List<Stock> Stocks)
{
    Stock temp = null;
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < Stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < Stocks.Count - 1; j++)
        {
            if (Compare(sortBy(Stocks[j]), sortBy(Stocks[j + 1])))
            {
                temp = Stocks[sortBy + 1];
                Stocks[sortBy + 1] = Stocks[sortBy];
                Stocks[sortBy] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak)
            break; /*early escape*/
    }
}

答案 1 :(得分:1)

您不应该假设GetFields返回的字段按特定顺序排列。

  

GetFields方法不会按特定顺序返回字段,例如按字母顺序或声明顺序。您的代码不得依赖于返回字段的顺序,因为该顺序会有所不同。

一种选择是像LINQ&#39; lambdas方法一样使用OrderBy。使用泛型类型还可以使代码更具可重用性,并使Compare方法更简单。

public void BubblesortBy<TSource, TKey>(Func<TSource, TKey> keySelector,
                                        List<TSource> stocks)
{
    int loopCount = 0;
    bool doBreak = true;

    for (int i = 0; i < stocks.Count; i++)
    {
        doBreak = true;
        for (int j = 0; j < stocks.Count - 1; j++)
        {
            if (Compare(keySelector(stocks[j]), keySelector(stocks[j+1])))
            {
                TSource temp = stocks[j + 1];
                stocks[j + 1] = stocks[j];
                stocks[j] = temp;
                doBreak = false;
            }
            loopCount++;
        }
        if (doBreak) { break; /*early escape*/ }
    }
}
private bool Compare<T>(T l, T r)
{
    return Comparer<T>.Default.Compare(l, r) > 0;
}

// use like
BubblesortBy(x => x.Close, myList);