Ошибка подписи OrderBy в книге Pro LINQ? - PullRequest
0 голосов
/ 30 марта 2009

Согласно Pro LINQ: языковой интегрированный запрос в C # 2008 , прототип оператора OrderBy равен

public static IOrderedEnumerable<T> OrderBy<T, K>(
    this IEnumerable<T> source,
    Func<T, K> keySelector)
where
    K : IComparable<K>

Но документация MSDN не имеет общего ограничения на TKey , что он должен иметь тип IComparable<TKey>

public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
    this IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector
)

Я в основном сортирую Инвентарь по Единице , а затем по Размеру .

    var sortedInventories = inventories
                            .OrderBy(inventory => inventory.Unit)
                            .OrderBy(inventory => inventory.Size);

Из приведенного выше фрагмента кода лямбда-выражения просто возвращают свойства инвентаря для сортировки. Это не похоже на выражение, которое возвращает IComparer<T>

Но, согласно логике, похоже, что лямбда-выражение должно иметь тип IComparer<T>.

Какой из них является правильным объявлением OrderBy?
(Apress.com Ошибка страницы не имеет информации об этом)

Вот пример приложения, которое я создал для тестирования OrderBy

public class Program
{
    public static void Main(string[] args)
    {
        var inventories = new[] {
            new Inventory { Unit = 1, Size = 2 },
            new Inventory { Unit = 2, Size = 4 },
            new Inventory { Unit = 3, Size = 6 },
        };
        var sortedInventories = inventories
                                .OrderBy(inventory => inventory.Unit)
                                .OrderBy(inventory => inventory.Size);

        foreach (var inventory in sortedInventories)
            Console.WriteLine("Unit: {0}; Size = {1}", inventory.Unit, inventory.Size);
    }
}

public class Inventory
{
    public int Unit { get; set; }
    public double Size { get; set; }
}

1 Ответ

4 голосов
/ 30 марта 2009

Измените свой второй «OrderBy» на «ThenBy». Вы в настоящее время используете все, так что это эффективно по размеру, а затем по единице, но неэффективно. Я не уверен, где вы думаете, IComparer<T> должен войти, если вы не укажете это в качестве другого аргумента. В основном он использует Comparer<T>.Default, если не указан отдельный компаратор.

В любом случае, ваш запрос должен быть:

var sortedInventories = inventories
                          .OrderBy(inventory => inventory.Unit)
                          .ThenBy(inventory => inventory.Size);

(С вашими тестовыми данными вы не можете определить разницу, потому что в каждом случае Size = Unit * 2. Попробуйте это с одним предметом, который имеет маленький юнит и большой размер.)

Да, похоже, что книга немного ошиблась в подписи - возможно, из-за того, что она изменилась незадолго до выпуска. Если вы в основном беспокоились о получении неправильных результатов, объяснение приведено выше.

...