Анонимная реализация IComparer

Можно ли определить анонимную реализацию IComparer?

Я считаю, что Java позволяет анонимным классам задаваться inline - делает С#?

Глядя на этот код, я хочу определить пользовательский IComparer встроенный

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

Ответ 1

Нет, С# в настоящее время не разрешает реализацию встроенного интерфейса; хотя это позволяет вам создавать делегаты встроенными с помощью лямбда-выражений и анонимных методов.

В вашем случае я бы предложил использовать ProjectionComparer, который упростил бы использование этой функции, например, перечисленную здесь.

Ответ 2

Как указано в одном из комментариев ниже,.Net 4.5 позволяет это посредством статического метода в классе Comparer < > , например. сравнивая два объекта на основе значения свойства в классе:

var comparer = Comparer<KilowattSnapshot>.Create( 
        (k1, k2) => k1.Kilowatt.CompareTo(k2.Kilowatt) );

Очевидно, что это можно использовать inline, а не назначать переменной.

Ответ 3

Даже если вы не можете создавать анонимные классы, реализующие интерфейсы, вы обычно можете использовать делегат сравнения вместо IComparer Interface в большинстве случаев (например, сортировка и т.д.):

Array.Sort(arr, (x, y) => 1);

Также существуют встроенные реализации IComparer, такие как Класс сравнения или Класс StringComparer...

Ответ 4

.NET Framework версии 4.5 предоставляет метод Comparer.Create(Comparison) для создания сопоставлений на основе указанного делегата сравнения (который может быть функцией лямбда). Однако людям, которые работают с более ранними версиями .NET, вероятно, потребуется реализовать нечто подобное.

Ответ 5

Нет, это невозможно. Однако вы можете получить стандартную реализацию IComparer<TKey> на Comparer<TKey>.Default. В противном случае вам нужно создать параметризованную реализацию и использовать экземпляр этого.

Ответ 6

С# не позволяет реализовать интерфейсы с использованием анонимных внутренних классов inline, в отличие от Java. Для простых сравнений (т.е. Сравнения с одним ключом) в С# есть лучший способ сделать это. Вы можете просто использовать метод .OrderBy() и передать в lambda выражение с указанием ключа.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;


namespace Test{
    public class Test{
        public static void Main(){
            IList<int> mylist = new List<int>();
            for(int i=0; i<10; i++) mylist.Add(i);
            var sorted = mylist.OrderBy( x => -x );
            foreach(int x in sorted)
                Console.WriteLine(x);
        }
    }
}

Ответ 7

Взгляните на эти 2 вопроса SO, они решают по существу ту же проблему

Использование отличия со списком пользовательского объекта

Оберните делегата в IEqualityComparer

Если вы пойдете так, вам следует обратить особое внимание на комментарии Slaks и ответить Dan Tao о реализации hashcode

Ответ 8

Array.Sort(arrayName, (x, y) = > string.Compare(x.Name, y.Name, StringComparison.CurrentCulture));