什么是过滤ArrayList内容的最佳方法?

4

假设我有一个USBDevice对象的ArrayList。每个USBDevice都有ProductID和VendorID属性(以及其他属性)。我想创建另一个ArrayList,它是第一个ArrayList的子集,仅包含与特定VID匹配的USBDevice。如何最短地实现这一点?我还没有尝试过,但lambda表达式是否可以像这样使用...

ArrayList CompleteList = new ArrayList();
...
// Fill CompleteList with all attached devices....
...
ArrayList SubSetList = CompleteList.Where(d => d.VID == "10C4")
3个回答

5

你需要进行类型转换。编译器只知道ArrayList包含对象,但它不知道里面的对象类型,所以你需要告诉它。

ArrayList subSetList = new ArrayList(CompleteList.Cast<USBDevice>()
                                                 .Where(d => d.VID == "10C4")
                                                 .ToList());

但是这似乎有点无意义。为什么你在同一个项目中使用旧的ArrayList类和LINQ?你应该尝试开始使用System.Collections.Generic命名空间中的List<T>类,然后你的where表达式将无需任何转换即可正常工作,就像你想要的那样。


3
为了配合@Mark Byers的建议,使用List<T>,这里提供一些示例代码:
List<USBDevice> CompleteList = new List<USBDevice>();
CompleteList.Add(new USBDevice(){VID = "10C4", Other = "x"});
CompleteList.Add(new USBDevice() { VID = "10C4", Other = "x" });

//..Fill CompleteList with all attached devices....

List<USBDevice> SubSetList = new List<USBDevice>();
SubSetList = CompleteList.Where(d => d.VID.Equals("10C4")).ToList();

2

是的,你可以使用 Where。但是为了做到这一点,你需要将你的 ArrayList 转换为 USBDevice。这应该可以工作:

var subset = CompleteList.Cast<USBDevice>().Where(x =>d.VID = "10C4");

但如果您能使用Linq,为什么要使用ArrayLists?您应该使用像List这样的通用集合。

编辑:正如Nick在评论中指出的那样,如果您的ArrayList可能包含除USBDevice对象以外的任何内容,则建议使用OfType()。


2
如果他正在使用ArrayList,则列表中可能包含其他类型。使用.OfType <USBDevice>()而不是.Cast <USBDevice>()将避免无效类型的异常。 - Nick Gotch
1
@Nick:异常是好的——它们让您知道您犯了一个错误,而不是像什么都没发生一样继续下去。 - Mark Byers
@Mark:没错,但这取决于他为什么使用ArrayList。如果它是用来保存各种不继承自共同类型的“设备”,那么这将安全地过滤掉他不需要的内容。 - Nick Gotch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接