【发布时间】:2012-04-09 19:57:37
【问题描述】:
如果我尝试在 IEnumerable<T> 对象图的多个级别过滤结果,是否有首选的链接扩展方法的方法来执行此操作?
我对任何扩展方法和 lambda 用法持开放态度,但我不希望使用 LINQ 语法来与代码库的其余部分保持一致。
将过滤推送到SelectMany() 方法的selector 还是仅仅链接另一个Where() 方法更好?还是有更好的解决方案?
我将如何确定最佳选择?在这个测试用例中,一切都直接在内存中可用。显然,下面的两个样本目前都产生了相同的正确结果;我只是在寻找一个或另一个(或另一种选择)更受欢迎的原因。
public class Test
{
// I want the first chapter of a book that's exactly 42 pages, written by
// an author whose name is Adams, from a library in London.
public Chapter TestingIEnumerableTExtensionMethods()
{
List<Library> libraries = GetLibraries();
Chapter chapter = libraries
.Where(lib => lib.City == "London")
.SelectMany(lib => lib.Books)
.Where(b => b.Author == "Adams")
.SelectMany(b => b.Chapters)
.First(c => c.NumberOfPages == 42);
Chapter chapter2 = libraries
.Where(lib => lib.City == "London")
.SelectMany(lib => lib.Books.Where(b => b.Author == "Adams"))
.SelectMany(b => b.Chapters.Where(c => c.NumberOfPages == 42))
.First();
}
这是示例对象图:
public class Library
{
public string Name { get; set; }
public string City { get; set; }
public List<Book> Books { get; set; }
}
public class Book
{
public string Name { get; set; }
public string Author { get; set; }
public List<Chapter> Chapters { get; set; }
}
public class Chapter
{
public string Name { get; set; }
public int NumberOfPages { get; set; }
}
【问题讨论】:
-
可读性似乎差不多。性能取决于这是对对象的 linq 还是对其他任何东西的 linq;你为什么不测量一下看看?
-
你的查询总是以
libraries => books => chapters的形式 - 或者你可能有更复杂的关系(我猜这只是一个测试模型) -
@NSGaga 他们总是采用这种分层形式,但你说得对,它只是一个测试模型,让读者更容易理解。从技术上讲,我正在使用 EDI (ANSI X12) 结构,因此文件、ISA、GS 和 ST 段。
-
@phoog 我同意测量它是一个好主意,但是在此处的示例和我正在处理的实际代码中,我没有任何迹象表明我的数据可能会发生多大的变化。在一种情况下,我将拥有
1 library,3 books,每个5000 chapters。下一次我可能有1 library和5000 books每个1 chapter。因为我无法准确预测其中之一,所以测量并不理想,我希望获得一般指导,让可读性成为更核心的目标。 -
我认为使用 LINQ 语法会使这样的代码更具可读性。而且我认为牺牲一致性是值得的。
标签: c# .net extension-methods ienumerable