在IList <t> </t>中订购商品

时间:2011-09-06 10:48:37

标签: c# list generics

我有一个清单

IList<IRule> allRules = new List<IRule>()

在该列表中我继续并随机添加不同类型的规则,即

allRules.add(DeleteRule1)
allRules.add(AddRule1)
allRules.add(DeleteRule2) 
allRules.add(EditRule1)
allRules.add(AddRule2)
allRules.add(DeleteRule3)

所有这一切都很好,我想弄清楚的是我需要对这个列表进行排序,所以它首先包含所有的AddRules然后是EditRules,最后是DeleteRules。

任何人都可以指定我可以采取的方法吗?

如果这没有意义,请告诉我,我会尝试更详细地解释。

非常感谢

8 个答案:

答案 0 :(得分:5)

似乎没有一种内置方法可以对IList<T>进行排序。

选项1 :将变量声明为List<T>类型并使用List<T>.Sort Method

List<IRule> allRules = new List<IRule>();
allRules.add(DeleteRule);
...
allRules.Sort();

选项2 :将列表替换为已订购的新列表。

IList<IRule> allRules = new List<IRule>();
allRules.add(DeleteRule);
...
allRules = allRules.OrderBy(x => x).ToList();

选项3 :为IList&lt; T&gt;实施快速排序。

选项4 :选择一种不同的集合类型,自动将其元素保持在特定顺序。

答案 1 :(得分:3)

有一个SortedList类可能正是您正在寻找的

答案 2 :(得分:2)

您应该实现自己的IComparer,而不是在Sort方法中使用它。

答案 3 :(得分:2)

我假设您有三个实现IRule的类(AddRule,EditRule,DeleteRule)。

如果您可以将所有规则的类型从IList更改为List,则可以使用List<T>.Sort(Comparison<T>)方法。 Comparison是具有签名

的通用委托
public delegate int Comparison<in T>(T x,T y)

所以你需要这样的东西:

public int IRuleComparer(IRule first, IRule second)
{
  //build a table of type weights (this could be made static)
  Dictionary<Type, int> typeWeights = new Dictionary<Type, int>();
  typeWeights.Add(typeof(AddRule), 1);
  typeWeights.Add(typeof(EditRule), 2);
  typeWeights.Add(typeof(DeleteRule), 3);

  //get the types of the arguments
  Type firstType = first.GetType();
  Type secondType = second.GetType();

  //are the types valid?
  if (!typeWeights.ContainsKey(firstType))
     throw new Exception("invalid first type");

  if (!typeWeights.ContainsKey(secondType))
     throw new Exception("invalid second type");

  //compare the weights of the types
  return typeWeights[firstType].CompareTo(typeWeights[secondType]);
}

另外,请注意Sort实现使用快速排序算法,这不是一个稳定的排序,即它可能会混乱AddRule的相对顺序,因此在您的示例中,AddRule2可以在AddRule1之前排序。


或者,您可以使用LINQ,如下所示:

public int GetRuleWeight(IRule item)
{
   //build a table of type weights (this could be made static)
   Dictionary<Type, int> typeWeights = new Dictionary<Type, int>();
   typeWeights.Add(typeof(AddRule), 1);
   typeWeights.Add(typeof(EditRule), 2);
   typeWeights.Add(typeof(DeleteRule), 3);

  Type itemType = item.GetType();

  if (!typeWeights.ContainsKey(itemType))
     throw new Exception("invalid type");

  return typeWeights[itemType];
}

allRules = allRules.OrderBy(item => GetRuleWeight(item)).ToList();

这将与IList一起使用(即使使用IEnumerable),因此您不必更改allRules的类型。

答案 4 :(得分:1)

List has a sort method你可以传递一个可以为你做比较算法的比较器。

using System;
using System.Collections.Generic;

public class Example
{
    private static int MyRuleComparer(Rule x, Rule y)
    {
      // return -1, 0 or 1 by comparing x & y
    }

    public static void Main()
    {
        List<Rule> allRules= new List<Rule>();
        allRules.Add(...);
        allRules.Add(...);
        allRules.Add(...);
        allRules.Add(...);

        allRules.Sort(MyRuleComparer);

    }
}

同样作为Sharique says,您可以使用SortedList类。这使用IComparer实例来完成工作:

使用System;     使用System.Collections.Generic;

public class Example
{
    public class MyComparer : IComparer  {
       int IComparer.Compare( Object x, Object y )  
       {
          // return -1, 0 or 1 by comparing x & y
       } 
    }  

    public static void Main()
    {
        SortedList allRules = new SortedList(new MyComparer ())
        allRules.Add(...); // Sorted each time
        allRules.Add(...); // Sorted each time
        allRules.Add(...); // Sorted each time
        allRules.Add(...); // Sorted each time
    }
}

答案 5 :(得分:1)

一种简单的方法是为每种类型创建3个单独的列表,然后将项目从AddRulesList和EditRulesList ..etc复制回列表,这很快,只需要太多循环。

如果你想成为通用的并依赖于内置的排序功能,你需要为IRule类型实现比较操作

http://codebetter.com/davidhayden/2005/03/06/implementing-icomparer-for-sorting-custom-objects/

答案 6 :(得分:0)

List<T> Class

  

不保证列表已排序。您必须对列表进行排序   在执行需要的操作(例如BinarySearch)之前   列表要排序。

您可能希望查看SortedList(但它不是类型安全的),或添加某种类型或Order归档到IRule,然后使用IEnumerable<T>.OrderBy(...)排序

修改

generic version of SortedList

答案 7 :(得分:0)

我会说简单,因为我猜我们不是在谈论一个巨大的清单。

Assmptions:C#3,以及适当的类或接口AddRuleEditRuleDeleteRule存在

var sortedRules = 
           allRules.OfType<AddRule>()
   .Concat(allRules.OfType<EditRule>())
   .Concat(allRules.OfType<DeleteRule>());