我有一个清单
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。
任何人都可以指定我可以采取的方法吗?
如果这没有意义,请告诉我,我会尝试更详细地解释。
非常感谢
答案 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)
不保证列表已排序。您必须对列表进行排序 在执行需要的操作(例如BinarySearch)之前 列表要排序。
您可能希望查看SortedList
(但它不是类型安全的),或添加某种类型或Order
归档到IRule
,然后使用IEnumerable<T>.OrderBy(...)
排序
修改强>
答案 7 :(得分:0)
我会说简单,因为我猜我们不是在谈论一个巨大的清单。
Assmptions:C#3,以及适当的类或接口AddRule
,EditRule
,DeleteRule
存在
var sortedRules =
allRules.OfType<AddRule>()
.Concat(allRules.OfType<EditRule>())
.Concat(allRules.OfType<DeleteRule>());