过滤数组列表内容的最佳方法是什么?
假设我有一个USBDevice对象的ArrayList。每个USB设备都有ProductID和VendorID属性(等等)。我想创建另一个ArrayList,它是第一个仅包含与特定VID匹配的USBDevice的子集。做这件事的最简单方法是什么?我还没有试过这个,但可以使用lambda表达式,像这样...过滤数组列表内容的最佳方法是什么?
ArrayList CompleteList = new ArrayList();
...
// Fill CompleteList with all attached devices....
...
ArrayList SubSetList = CompleteList.Where(d => d.VID == "10C4")
你需要一个演员。编译器知道的关于ArrayLists的唯一事情是它们包含对象。它不知道里面的物体的类型,所以你必须告诉它。
ArrayList subSetList = new ArrayList(CompleteList.Cast<USBDevice>()
.Where(d => d.VID == "10C4")
.ToList());
但这似乎没有意义。为什么在同一个项目中使用旧的ArrayList
类和LINQ?您应该尝试开始在System.Collections.Generic
名称空间中使用List<T>
类,然后您的where表达式将在没有任何投射的情况下工作,就像您想的那样。
是的,你可以使用Where。但为了做到这一点,您需要将您的ArrayList强制转换为USBDevice。这应该工作:
var subset = CompleteList.Cast<USBDevice>().Where(x =>d.VID = "10C4");
但是,如果你能够使用Linq,为什么你使用ArrayLists?您应该使用像List这样的通用集合。
编辑:正如尼克在评论中指出的那样,如果您的ArrayList可能包含USBDevice对象以外的其他任何东西,建议使用OfType()。
要随着使用列表<牛逼>的@马克拜尔斯的建议,走,这里是一些示例代码:
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();
这个例子很完美。谢谢! – PICyourBrain 2010-02-23 19:03:26
如果他使用一个ArrayList其他类型的可在列表中。使用.OfType()而不是.Cast ()将避免无效类型的例外。 –
2010-02-23 15:50:24
@Nick:例外情况很好 - 他们让你知道你犯了一个错误,而不是像没有任何错误一样继续。 – 2010-02-23 15:53:23
@Mark:真的,但这取决于他为什么使用ArrayList。如果要保存各种不能从普通类型继承的“设备”,这将安全地过滤掉他不需要的东西。 – 2010-02-23 16:08:06