在C#中对IList进行排序

时间:2020-03-05 18:40:35  来源:igfitidea点击:

所以我今天遇到了一个有趣的问题。我们有一个返回IList的WCF Web服务。在我想对其进行排序之前,这并不是什么大不了的事情。

事实证明,IList接口没有内置的排序方法。

我最终使用ArrayList.Adapter(list).Sort(new MyComparer())方法解决了这个问题,但对我来说似乎有点"贫民窟"。

我玩弄了一个扩展方法,还继承了IList并实现了我自己的Sort()方法以及转换为List,但是这些似乎都不是太优雅了。

所以我的问题是,有人对IList进行排序是否有一种优雅的解决方案

解决方案

回答

我将不得不做类似的事情(将其转换为更具体的类型)。

也许将其放入T列表而不是ArrayList中,以便获得类型安全性以及实现比较器方式的更多选项。

回答

将IList转换为List <T>或者其他通用集合,然后可以使用System.Linq名称空间轻松地对其进行查询/排序(它将提供大量扩展方法)

回答

使用LINQ To Objects为我们排序怎么样?

假设我们有一个" IList <Car>",并且该汽车具有" Engine"属性,我相信我们可以进行如下排序:

from c in list
orderby c.Engine
select c;

编辑:我们需要在这里快速获得答案。由于我给出的语法与其他答案略有不同,因此我将保留我的答案,但是所提供的其他答案同样有效。

回答

我们可以使用LINQ:

using System.Linq;

IList<Foo> list = new List<Foo>();
IEnumerable<Foo> sortedEnum = list.OrderBy(f=>f.Bar);
IList<Foo> sortedList = sortedEnum.ToList();

回答

这是使用更强类型的示例。不确定是否一定是最好的方法。

static void Main(string[] args)
{
    IList list = new List<int>() { 1, 3, 2, 5, 4, 6, 9, 8, 7 };
    List<int> stronglyTypedList = new List<int>(Cast<int>(list));
    stronglyTypedList.Sort();
}

private static IEnumerable<T> Cast<T>(IEnumerable list)
{
    foreach (T item in list)
    {
        yield return item;
    }
}

Cast函数只是对3.5扩展方法的重新实现,该扩展方法是作为常规静态方法编写的。不幸的是,它非常丑陋且冗长。

回答

在VS2008中,当我单击服务引用并选择"配置服务引用"时,有一个选项可以选择客户端如何反序列化从服务返回的列表。

值得注意的是,我可以在System.Array,System.Collections.ArrayList和System.Collections.Generic.List之间进行选择

回答

在此找到了不错的帖子,并认为我会分享。在这里查看

基本上。

我们可以创建以下类和IComparer类

public class Widget {
    public string Name = string.Empty;
    public int Size = 0;

    public Widget(string name, int size) {
    this.Name = name;
    this.Size = size;
}
}

public class WidgetNameSorter : IComparer<Widget> {
    public int Compare(Widget x, Widget y) {
        return x.Name.CompareTo(y.Name);
}
}

public class WidgetSizeSorter : IComparer<Widget> {
    public int Compare(Widget x, Widget y) {
    return x.Size.CompareTo(y.Size);
}
}

然后,如果我们有一个IList,则可以像这样对它进行排序。

List<Widget> widgets = new List<Widget>();
widgets.Add(new Widget("Zeta", 6));
widgets.Add(new Widget("Beta", 3));
widgets.Add(new Widget("Alpha", 9));

widgets.Sort(new WidgetNameSorter());
widgets.Sort(new WidgetSizeSorter());

但是请查看此站点以获取更多信息...在此处查看

回答

using System.Linq;

var yourList = SomeDAO.GetRandomThings();
yourList.ToList().Sort( (thing, randomThing) => thing.CompareThisProperty.CompareTo( randomThing.CompareThisProperty ) );

相当!贫民窟。

回答

在我寻找原始帖子中描述的确切问题的解决方案时找到了这个线程。但是,没有一个答案完全符合我的情况。布罗迪的答案非常接近。这是我发现的情况和解决方案。

我有NHibernate返回的两个相同类型的IList,并将两个IList合并为一个,因此需要进行排序。

就像Brody所说的那样,我在对象(ReportFormat)上实现了ICompare,这是我的IList的类型:

public class FormatCcdeSorter:IComparer<ReportFormat>
    {
       public int Compare(ReportFormat x, ReportFormat y)
        {
           return x.FormatCode.CompareTo(y.FormatCode);
        }
    }

然后,我将合并的IList转换为相同类型的数组:

ReportFormat[] myReports = new ReportFormat[reports.Count]; //reports is the merged IList

然后对数组进行排序:

Array.Sort(myReports, new FormatCodeSorter());//sorting using custom comparer

由于一维数组实现了System.Collections.Generic.IList <T>接口,因此可以像使用原始IList一样使用该数组。

回答

这是有效的解决方案吗?

IList<string> ilist = new List<string>();
        ilist.Add("B");
        ilist.Add("A");
        ilist.Add("C");

        Console.WriteLine("IList");
        foreach (string val in ilist)
            Console.WriteLine(val);
        Console.WriteLine();

        List<string> list = (List<string>)ilist;
        list.Sort();
        Console.WriteLine("List");
        foreach (string val in list)
            Console.WriteLine(val);
        Console.WriteLine();

        list = null;

        Console.WriteLine("IList again");
        foreach (string val in ilist)
            Console.WriteLine(val);
        Console.WriteLine();

结果是:
清单

一种
C

列表
一种

C

再次列出
一种

C

回答

对于网格排序很有用,此方法根据属性名称对列表进行排序。如下例所示。

List<MeuTeste> temp = new List<MeuTeste>();

    temp.Add(new MeuTeste(2, "ramster", DateTime.Now));
    temp.Add(new MeuTeste(1, "ball", DateTime.Now));
    temp.Add(new MeuTeste(8, "gimm", DateTime.Now));
    temp.Add(new MeuTeste(3, "dies", DateTime.Now));
    temp.Add(new MeuTeste(9, "random", DateTime.Now));
    temp.Add(new MeuTeste(5, "call", DateTime.Now));
    temp.Add(new MeuTeste(6, "simple", DateTime.Now));
    temp.Add(new MeuTeste(7, "silver", DateTime.Now));
    temp.Add(new MeuTeste(4, "inn", DateTime.Now));

    SortList(ref temp, SortDirection.Ascending, "MyProperty");

    private void SortList<T>(
    ref List<T> lista
    , SortDirection sort
    , string propertyToOrder)
    {
        if (!string.IsNullOrEmpty(propertyToOrder)
        && lista != null
        && lista.Count > 0)
        {
            Type t = lista[0].GetType();

            if (sort == SortDirection.Ascending)
            {
                lista = lista.OrderBy(
                    a => t.InvokeMember(
                        propertyToOrder
                        , System.Reflection.BindingFlags.GetProperty
                        , null
                        , a
                        , null
                    )
                ).ToList();
            }
            else
            {
                lista = lista.OrderByDescending(
                    a => t.InvokeMember(
                        propertyToOrder
                        , System.Reflection.BindingFlags.GetProperty
                        , null
                        , a
                        , null
                    )
                ).ToList();
            }
        }
    }