我有一个类Bookstore
,它实现了一个接口IBookstore
。
Bookstore
将私人财产作为一系列图书:private List<Book> AllBooks;
我不想通过界面公开整本书籍清单。相反,我希望用户根据某些属性查询书籍。所以,在IBookstore
我有以下内容:
public interface IBookstore
{
IList<Book> SelectedBooks;
}
public class Bookstore : IBookstore
{
private List<Book> AllBooks;
public IList<Book> SelectedBooks { get; set; }
}
我想要做的是在名为SearchBooks
的方法中创建一个方法,该方法将在AllBooks列表中搜索包含各种属性的所有条目,然后将SelectedBooks
与结果一起设置。所以,我的用法如下:
Bookstore myStore = new Bookstore();
...
myStore.SearchBooks( A BUNCH OF CRITERIA );
myStore.SelectedBooks; // contains books selected by the criteria passed to SearchBooks above
为什么我要这样做:
SelectedBooks
。我不想
多次运行搜索。myBookstore
的属性。此对象只创建一次并在许多地方使用,因此我希望能够在许多地方访问相同的SelectedBooks
,而无需重新构造它。将其存储为当地财产是不可取的;即,我不想List<Book> myBooks = myStore.SearchBooks( A BUNCH OF CRITERIA);
。我有充分的理由这样做。我的问题
鉴于Book
有许多属性,例如Title
,Author
,Date
等等,将一组搜索条件任意传递给SearchBooks
的最简单方法是什么,以便我可以在{{}}内私下搜索我的列表{1}}?
例如,如果我可以访问我的应用程序中的整个列表,我可以使用Linq。我可以将Linq查询传递给方法,并让查询在Bookstore
内私下执行吗?
答案 0 :(得分:4)
我可以将Linq查询传递给方法并让查询在myBookstore中私有执行吗?
您可以传递委托:
public void SearchBooks(Func<IEnumerable<Book>, IEnumerable<Book>> query)
{
SelectedBooks = query(AllBooks).ToList();
}
呼叫示例:
myStore.SearchBooks(c => c.Where(b => b.Title == "test" && b.Author == "author"));
或只是一组谓词:
public void SearchBooks(params Func<Book, bool>[] predicates)
{
var query = AllBooks.AsEnumerable();
foreach(var p in predicates)
query = query.Where(p);
SelectedBooks = query.ToList();
}
呼叫示例:
myStore.SearchBooks(x => x.Title == "test", x => x.Author == "author");
答案 1 :(得分:0)
我个人不会经历尝试抽象查询概念的所有麻烦。相反,直接在书籍列表中使用LINQ。
您可以将图书清单公开为可枚举的序列。
public interface IBookstore
{
IEnumerable<Book> Books;
}
然后你可以通过LINQ以你喜欢的任何方式查询它。
IBookstore store; // Some store.
var johngreenBooks = from book in store.Books
where book.Author == "John Green"
orderby book.Title
select book;
如果您不想在每次枚举时评估查询,请将其设为列表或数组。
var johngreenBookArray = johngreenBooks.ToArray();
你可以传递这个数组(或列表),或者把它塞到某个地方。在我看来,我用来选择一些书籍的查询独立于书店,所以我不会将结果存储在商店中。