Linq与IComparer相比

时间:2013-06-05 09:20:03

标签: linq icomparer

我看过这个类看起来像这样:

    /// <summary>
    /// Provides an internal structure to sort the query parameter
    /// </summary>
    protected class QueryParameter
    {
        public QueryParameter(string name, string value)
        {
            Name = name;
            Value = value;
        }

        public string Name { get; private set; }
        public string Value { get; private set; }
    }

    /// <summary>
    /// Comparer class used to perform the sorting of the query parameters
    /// </summary>
    protected class QueryParameterComparer : IComparer<QueryParameter>
    {
        public int Compare(QueryParameter x, QueryParameter y)
        {
            return x.Name == y.Name 
                ? string.Compare(x.Value, y.Value) 
                : string.Compare(x.Name, y.Name);
        }
    }

然后在执行排序的代码中稍后调用:

parameters.Sort(new QueryParameterComparer());

一切正常。 我认为创建一个只有名称值的QueryParameter类是浪费时间,使用Dictionary可能会更好。用字典,而不是使用Sort(new QueryParameterComparer());我想我可以这样做:

parameters.ToList().Sort((x, y) => x.Key == y.Key ? string.Compare(x.Value, y.Value) : string.Compare(x.Key, y.Key));

代码编译得很好,但我不确定它是否正常工作,因为列表似乎按照它放入的顺序输出。 那么,任何人都可以告诉我,如果我正确地这样做,或者我错过了一些简单的东西吗?

干杯 / r3plica

3 个答案:

答案 0 :(得分:2)

List<T>.Sort方法不是LINQ的一部分。

在调用ToList()之前,您可以使用OrderBy / ThenBy扩展方法:

parameters = parameter.OrderBy(x => x.Key).ThenBy(x => x.Value).ToList();

答案 1 :(得分:2)

从您的代码中,我猜测parameters是您的字典,而您正在致电

parameters.ToList().Sort(...);

然后继续使用parameters

ToList()创建一个新列表;然后,您正在对此列表进行排序,将其丢弃。您根本没有对parameters进行排序,事实上您无法对其进行排序,因为它是字典。

您需要的是

var parametersList = parameters.ToList();
parametersList.Sort(...);

其中...与以前的排序相同。

您也可以

var parametersList = parameters.OrderBy(...).ToList();

这是一种更加LINQ-y的做事方式。

甚至可能只做例如。

foreach(var kvp in parameters.OrderBy(...))

(或者你计划使用排序的序列)如果你使用排序的序列比你更改字典更频繁(即没有意义)缓存已排序的版本,因为原始数据发生了很大的变化。)


需要注意的另一点 - 字典不能包含重复的密钥,因此无需再检查x.Key == y.Key - 您只需要通过(x, y) => string.Compare(x.Key, y.Key)进行排序

我在这里要小心 - 从它的外观来看,原始代码 支持重复键,所以通过switchnig到字典你可能会破坏某些东西。

答案 2 :(得分:0)

Dictionary只相当于两个哈希映射,并且允许您使用costant时间O(1)访问任何alement(给定键)(因为在哈希表上进行查找搜索)。

因此,如果您因为打算稍后进行双子搜索而订购元素,则不需要直接使用字典(或者如果要查询字典中的值,则可以使用几个字典相同的元素,但切换键值对。)

正如有人在我之前写的那样,如果你质疑如何使用linq订购列表,你应该使用linq和orderby thenby。