在 C# 中对 IList 进行排序
所以今天我遇到了一个有趣的问题。 我们有一个返回 IList 的 WCF Web 服务。 没什么大不了的,直到我想对它进行排序。
原来 IList 接口没有内置排序方法。
我最终使用 ArrayList.Adapter(list).Sort(new MyComparer()) 方法来解决问题,但它似乎对我来说有点“贫民窟”。
我尝试编写一个扩展方法,还尝试继承 IList 并实现我自己的 Sort() 方法以及转换为 List,但这些似乎都不太优雅。
所以我的问题是,是否有人有一个优雅的解决方案来对 IList 进行排序
So I came across an interesting problem today. We have a WCF web service that returns an IList. Not really a big deal until I wanted to sort it.
Turns out the IList interface doesn't have a sort method built in.
I ended up using the ArrayList.Adapter(list).Sort(new MyComparer())
method to solve the problem but it just seemed a bit "ghetto" to me.
I toyed with writing an extension method, also with inheriting from IList and implementing my own Sort() method as well as casting to a List but none of these seemed overly elegant.
So my question is, does anyone have an elegant solution to sorting an IList
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
将您的
IList
转换为List
或其他一些通用集合,然后您可以使用System.Linq
命名空间(它将提供一堆扩展方法)Convert your
IList
intoList<T>
or some other generic collection and then you can easily query/sort it usingSystem.Linq
namespace (it will supply bunch of extension methods)如果你问我的话,这看起来要简单得多。 这对我来说非常有效。
您可以使用 Cast() 将其更改为 IList,然后使用 OrderBy():
其中 T 是类型,例如。 Model.Employee 或 Plugin.ContactService.Shared.Contact
然后您可以使用 for 循环及其 DONE。
This looks MUCH MORE SIMPLE if you ask me. This works PERFECTLY for me.
You could use Cast() to change it to IList then use OrderBy():
WHERE T is the type eg. Model.Employee or Plugin.ContactService.Shared.Contact
Then you can use a for loop and its DONE.
这是一个有效的解决方案吗?
结果是:
列表
乙
A
C
列表
A
乙
C I
再次列出
A
乙
C
Is this a valid solution?
The result was:
IList
B
A
C
List
A
B
C
IList again
A
B
C
在VS2008中,当我单击服务引用并选择“配置服务引用”时,有一个选项可以选择客户端如何反序列化从服务返回的列表。
值得注意的是,我可以在 System.Array、System.Collections.ArrayList 和 System.Collections.Generic.List 之间进行选择
In VS2008, when I click on the service reference and select "Configure Service Reference", there is an option to choose how the client de-serializes lists returned from the service.
Notably, I can choose between System.Array, System.Collections.ArrayList and System.Collections.Generic.List
这是使用更强类型的示例。 但不确定这是否一定是最好的方法。
Cast函数只是3.5自带的扩展方法的重新实现,写成普通的静态方法。 不幸的是,它非常丑陋且冗长。
Here's an example using the stronger typing. Not sure if it's necessarily the best way though.
The Cast function is just a reimplementation of the extension method that comes with 3.5 written as a normal static method. It is quite ugly and verbose unfortunately.
太漂亮了!贫民窟。
That's pretty !ghetto.
发现了一篇关于此的好帖子,我想分享一下。 在这里查看
基本上。
您可以创建以下类和 IComparer 类
然后如果您有一个 IList,您可以像这样对它进行排序。
但请查看此网站以获取更多信息...在这里查看
Found a good post on this and thought I'd share. Check it out HERE
Basically.
You can create the following class and IComparer Classes
Then If you have an IList, you can sort it like this.
But Checkout this site for more information... Check it out HERE
您可以使用 LINQ:
You can use LINQ:
这个问题启发我写了一篇博客文章: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
我认为,理想情况下,.NET Framework 将包含一个静态接受 IList的排序方法,但下一个最好的事情是创建您自己的扩展方法。 创建几个允许您对 IList进行排序的方法并不太难。 就像 List一样。 作为奖励,您可以使用相同的技术重载 LINQ OrderBy 扩展方法,这样无论您使用的是 List.Sort、IList.Sort 还是 IEnumerable.OrderBy,都可以使用完全相同的语法。
使用这些扩展,可以像列表一样对 IList 进行排序:
帖子中有更多信息: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
This question inspired me to write a blog post: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
I think that, ideally, the .NET Framework would include a static sorting method that accepts an IList<T>, but the next best thing is to create your own extension method. It's not too hard to create a couple of methods that will allow you to sort an IList<T> as you would a List<T>. As a bonus you can overload the LINQ OrderBy extension method using the same technique, so that whether you're using List.Sort, IList.Sort, or IEnumerable.OrderBy, you can use the exact same syntax.
With these extensions, sort your IList just like you would a List:
There's more info in the post: http://blog.velir.com/index.php/2011/02/17/ilistt-sorting-a-better-way/
@DavidMills 接受的答案非常好,但我认为它可以改进。 其一,当框架已包含静态方法
Comparer.Create(Comparison)
时,无需定义ComparisonComparer
类。 此方法可用于动态创建IComparison
。此外,它将
IList
转换为IList
,这可能是危险的。 在我见过的大多数情况下,实现IList
的List
在幕后用于实现IList
,但是这个无法保证,并且可能导致代码脆弱。最后,重载的
List.Sort()
方法有 4 个签名,但仅实现了其中 2 个。List.Sort()
List.Sort(Comparison)
List.Sort(IComparer)< /code>
List.Sort(Int32, Int32, IComparer)
下面的类实现了所有 4 个
List.Sort()
签名IList
接口:用法:
这里的想法是利用底层
List
的功能来尽可能处理排序。 同样,我见过的大多数IList
实现都使用它。 如果底层集合是不同类型,则回退到使用输入列表中的元素创建List
的新实例,使用它进行排序,然后将结果复制回输入列表。 即使输入列表没有实现 IList 接口,这也将起作用。The accepted answer by @DavidMills is quite good, but I think it can be improved upon. For one, there is no need to define the
ComparisonComparer<T>
class when the framework already includes a static methodComparer<T>.Create(Comparison<T>)
. This method can be used to create anIComparison
on the fly.Also, it casts
IList<T>
toIList
which has the potential to be dangerous. In most cases that I have seen,List<T>
which implementsIList
is used behind the scenes to implementIList<T>
, but this is not guaranteed and can lead to brittle code.Lastly, the overloaded
List<T>.Sort()
method has 4 signatures and only 2 of them are implemented.List<T>.Sort()
List<T>.Sort(Comparison<T>)
List<T>.Sort(IComparer<T>)
List<T>.Sort(Int32, Int32, IComparer<T>)
The below class implements all 4
List<T>.Sort()
signatures for theIList<T>
interface:Usage:
The idea here is to leverage the functionality of the underlying
List<T>
to handle sorting whenever possible. Again, mostIList<T>
implementations that I have seen use this. In the case when the underlying collection is a different type, fallback to creating a new instance ofList<T>
with elements from the input list, use it to do the sorting, then copy the results back to the input list. This will work even if the input list does not implement theIList
interface.你将不得不做类似我认为的事情(将其转换为更具体的类型)。
也许将其放入 T 的列表而不是 ArrayList 中,以便获得类型安全性以及如何实现比较器的更多选项。
You're going to have to do something like that i think (convert it into a more concrete type).
Maybe take it into a List of T rather than ArrayList, so that you get type safety and more options for how you implement the comparer.
使用 LINQ To Objects 为您排序怎么样?
假设您有一个
IList
,并且汽车有一个Engine
属性,我相信您可以按如下方式排序:编辑:您确实需要快速在这里得到答案。 由于我提出的语法与其他答案略有不同,因此我将留下我的答案 - 但是,提出的其他答案同样有效。
How about using LINQ To Objects to sort for you?
Say you have a
IList<Car>
, and the car had anEngine
property, I believe you could sort as follows:Edit: You do need to be quick to get answers in here. As I presented a slightly different syntax to the other answers, I will leave my answer - however, the other answers presented are equally valid.
对于网格排序很有用,此方法根据属性名称对列表进行排序。 如下示例所示。
Useful for grid sorting this method sorts list based on property names. As follow the example.
当我正在寻找原始帖子中描述的确切问题的解决方案时发现了这个线程。 然而,没有一个答案完全符合我的情况。 布罗迪的回答非常接近。 这是我的情况和我找到的解决方案。
我有两个由 NHibernate 返回的相同类型的 IList,并将这两个 IList 合并为一个,因此需要排序。
就像 Brody 所说,我在对象(ReportFormat)上实现了 ICompare,它是我的 IList 的类型:
然后将合并的 IList 转换为相同类型的数组:
然后对数组进行排序:
因为一维数组实现了接口
System.Collections.Generic.IList
,该数组可以像原始IList一样使用。Found this thread while I was looking for a solution to the exact problem described in the original post. None of the answers met my situation entirely, however. Brody's answer was pretty close. Here is my situation and solution I found to it.
I have two ILists of the same type returned by NHibernate and have emerged the two IList into one, hence the need for sorting.
Like Brody said I implemented an ICompare on the object (ReportFormat) which is the type of my IList:
I then convert the merged IList to an array of the same type:
Then sort the array:
Since one-dimensional array implements the interface
System.Collections.Generic.IList<T>
, the array can be used just like the original IList.