Сортировать список объектов интерфейса - PullRequest
2 голосов
/ 29 февраля 2012

У меня есть пара классов, которые реализуют интерфейс, IFoo. Мне нужно отобразить список объектов этих классов в таблице, которую я бы хотел отсортировать по любому произвольному столбцу в таблице. Итак, источником данных для таблицы является List<IFoo>.

Проблема, с которой я столкнулся, заключается в том, что стандартный способ реализации IComparable или IComparer для объектов, используемых в списке, требует статического метода, но статические методы не допускаются в интерфейсах. Итак, вопрос сводится к следующему: как можно сортировать List<IFoo>?

Ответы [ 3 ]

8 голосов
/ 29 февраля 2012

IComparable

Я не знаю, что дает вам представление о том, что вам нужно использовать статический метод, но это не правильно.

Вы можете заставить все ваши IFoo реализации реализовать IComparable<IFoo>, добавив его в IFoo:

interface IFoo : IComparable<IFoo> 
{ 
    int Value { get; set; } // for example's sake
}

class SomeFoo : IFoo
{
    public int Value { get; set; }

    public int CompareTo(IFoo other)
    {
        // implement your custom comparison here...

        return Value.CompareTo(other.Value); // e.g.
    }
}

Затем просто отсортируйте ваш List<IFoo> так:

list.Sort();

Сортировка по произвольному столбцу

Вы изначально заявили, что хотите отсортировать по произвольному столбцу в таблице объектов IFoo. Это сложнее; вам нужно иметь возможность сортировать список объектов по любому из их открытых свойств, поэтому базовая реализация IComparable<IFoo>, описанная выше, не собирается его сокращать.

Решением является создание PropertyComparer<T> класса, который реализует IComparer<T> и будет сортировать по любое свойство T. Вы могли бы написать это специально для IFoo, но в какой-то момент каждый разработчик сталкивается с этой проблемой и заканчивает тем, что написал общий компаратор свойств, который попытается отсортировать любой тип. В результате вы можете зайти в Google "C # Property Comparer" и вы обязательно получите несколько просмотров. Вот простой:

http://www.codeproject.com/Articles/16200/Simple-PropertyComparer

3 голосов
/ 29 февраля 2012

Я не уверен, с какой проблемой вы столкнулись, потому что я только что провел быстрый тест и смог отсортировать список IFoo.Смотрите ниже, как я это сделал.Если это не соответствует вашим потребностям, не могли бы вы дать более подробную информацию?

var fooList = new List<IFoo>{new testFoo{key=3}, new testFoo{key=1}};
fooList.Sort(
    delegate(IFoo obj1, IFoo obj2){return obj1.key.CompareTo(obj2.key);});

Интерфейс и бетон

public interface IFoo
{
     int key{get;set;}
}

public class testFoo:IFoo
{
    public int key {get;set;}
}
0 голосов
/ 29 февраля 2012

Если вы используете C # 3/4, вы можете использовать лямбда-выражение ..

Этот пример показывает, как вы можете сортировать по различным свойствам интерфейса IFoo:

void Main()
{
    List<IFoo> foos = new List<IFoo>
    {
        new Bar2{ Name = "Pqr", Price = 789.15m, SomeNumber = 3 },
        new Bar2{ Name = "Jkl", Price = 444.25m, SomeNumber = 1 },
        new Bar1{ Name = "Def", Price = 222.5m, SomeDate = DateTime.Now },
        new Bar1{ Name = "Ghi", Price = 111.1m, SomeDate = DateTime.Now },
        new Bar1{ Name = "Abc", Price = 123.45m, SomeDate = DateTime.Now },
        new Bar2{ Name = "Mno", Price = 564.33m, SomeNumber = 2 }

    };

    foos.Sort((x,y) => x.Name.CompareTo(y.Name));
    foreach(IFoo foo in foos)
    {
        Console.WriteLine(foo.Name);
    }

    foos.Sort((x,y) => x.Price.CompareTo(y.Price));
    foreach(IFoo foo in foos)
    {
        Console.WriteLine(foo.Price);
    }
}

interface IFoo
{
    string Name { get; set; }
    decimal Price { get; set; }
}

class Bar1 : IFoo
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public DateTime SomeDate { get; set; }
}

class Bar2 : IFoo
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int SomeNumber { get; set; }
}

Выход:

Abc
Def
Ghi
Jkl
Mno
Pqr
111.1
222.5
333.33
444.25
555.45
666.15
...