【问题标题】:How to sort an iList (With linq or without) [duplicate]如何对 iList 进行排序(使用或不使用 linq)[重复]
【发布时间】:2012-01-08 04:37:17
【问题描述】:

可能重复:
Sorting an IList in C#

我有以下方法,我需要对传递给它的 iList 对象进行排序(在此方法内)。我尝试过 linq,但由于它是一个接口,所以我遇到了错误。

提前致谢

private void AddListToTree(ComponentArt.Web.UI.TreeView treeView, IList list)
{
//NEED TO SORT THE LIST HERE
}

请注意我的类型是动态的。

我认为我应该创建一个临时集合,如果从我的 IList 实例填充,对其进行排序,获取支持 IList 的对象的适当实例并使用它而不是我应该保持不变的 IList 的未排序实例。 所以我尝试获取如下类型:

Type[] listTypes = list.GetType().GetGenericArguments();
Type listType = null;
if (listTypes.Length > 0)
{
listType = listTypes[0];
}

但是我不能用这种类型创建一个新的列表

【问题讨论】:

    标签: c# .net sorting interface ilist


    【解决方案1】:

    您应该使用IList 的通用形式才能使用 LINQ 扩展方法:

    private void AddListToTree<T>(ComponentArt.Web.UI.TreeView treeView,
                                  IList<T> list)
    {
        var orderedList = list.OrderBy(t => t);
        // ...
    }
    

    如果你不能修改方法的签名但是你知道IList中的对象的类型,你可以使用Cast

    private void AddListToTree(ComponentArt.Web.UI.TreeView treeView,
                               IList list)
    {
        var orderedList = list.Cast<SomeType>().OrderBy(x => x);
        // ...
    }
    

    【讨论】:

    • 我无法更改方法类型。除了 LINQ 之外,还有什么方法可以对 List 接口对象进行排序?
    • +1 使用 IList 提供对诸如 orderby() 等通用方法的访问。
    • @SevAbedi:查看更新。这有帮助吗?不过需要您提前知道类型。
    • @SevAbedi,备份。无法更改签名的原因是什么?这三个类是否共享相同的基类或接口?你给定的IList 会混合在一起,同时包含不同类型的对象吗?除非提供更详细的问题,否则很难制定解决方案。
    • 不,这种方法行不通。 Cast&lt;T&gt; 不期望 Type 对象,也就是说,它不期望 .Cast&lt;typeof(int)&gt; 中的类型元数据,而是直接期望 T,如 .Cast&lt;int&gt;
    【解决方案2】:

    您可以使用Cast&lt;T&gt;() 将其更改为IList&lt;T&gt;,然后使用OrderBy()

    private void AddListToTree<T>(ComponentArt.Web.UI.TreeView treeView, IList list)
    {
        var ordered = list.Cast<T>().OrderBy(e => e);
    }
    

    您需要知道类型才能进行排序。

    【讨论】:

    • 这是一个 iList 不是一个列表
    • 好的,我明白了;更新了我的答案...
    • 我没有类型(T)
    • 你不需要知道类型才能排序吗...?
    【解决方案3】:

    对于 LINQ: 重复问题为:Sorting an IList in C#

    您也可以使用扩展方法将排序命令添加到 IList:Why is there no Sort for IList<T>?!?! (edited)'

    您可以执行以下操作(我不认可,但仍然可行)

    IList list;
    ArrayList al = new ArrayList(list);
    al.Sort();
    

    您还可以使用 IComparable: http://devpinoy.org/blogs/keithrull/archive/2007/03/23/sorting-a-generic-list-of-object-in-c-using-icomparable-and-anonymous-delegates.aspx

    http://foxsys.blogspot.com/2007/06/how-to-sort-generic-ilist.html

    【讨论】:

    • 我尝试了 ArrayList 方法,但出现以下错误:无法比较数组中的两个元素。
    • 请注意,使用 IList 的构造函数将导致 Sort 对新的 ArrayList(其中包含原始 IList 内容的副本)而不是原始 IList 进行排序。
    【解决方案4】:

    一种选择是使用ArrayList.Adapter 在IList 周围创建一个ArrayList 适配器,然后使用ArrayList.Sort 对其进行排序。这是如果您需要一个改变数组内容而不是返回排序枚举的就地排序操作。

    【讨论】:

      【解决方案5】:

      如果您无法更改签名或使用 LINQ,请使用扩展方法或自定义方法。

      @Ryan Ternier 列出的重复问题中给出的示例:

      LINQ:重复问题为: Sorting an IList in C#

      【讨论】:

      • Ryan 刚刚发布了一个内容更丰富的答案,所以请查看它以获取更多信息,我只是引用了他对这个问题的评论。
      【解决方案6】:

      一种方式(注意必须在from子句中指定item类型):

      IList list = new ArrayList();
      list.Add("z");
      list.Add("a");
      list.Add("c");
      
      IEnumerable<string> ordered =
          from string item in list
          orderby item
          select item;
      
      foreach (var s in ordered)
      {
          Console.WriteLine(s);
      }
      

      打印:

      一个
      C
      z

      注意:根据您后来的评论

      它们可以是 3 个不同类别的类型

      这行不通。我会认真考虑重构调用代码。

      如果您无法编辑类型,并且类型不应该在排序列表中混合,这里有一个选项:

      var one = list.OfType<TypeOne>().OrderBy(x => x.Id);
      var two = list.OfType<TypeTwo>().OrderBy(x => x.Name);
      var three = list.OfType<TypeThree>().OrderBy(x => x.Nom);
      
      var result =
          one.Cast<object>()
          .Concat(two.Cast<object>())
          .Concat(three.Cast<object>());
      

      【讨论】:

        猜你喜欢
        • 2011-10-21
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多