通过界面搜索列表

时间:2014-02-18 17:28:53

标签: c# interface

我有一个类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。我不想 多次运行搜索。
  • 我希望SelectedBooks列表是myBookstore的属性。此对象只创建一次并在许多地方使用,因此我希望能够在许多地方访问相同的SelectedBooks,而无需重新构造它。将其存储为当地财产是不可取的;即,我不想List<Book> myBooks = myStore.SearchBooks( A BUNCH OF CRITERIA);。我有充分的理由这样做。

我的问题

鉴于Book有许多属性,例如TitleAuthorDate等等,将一组搜索条件任意传递给SearchBooks的最简单方法是什么,以便我可以在{{}}内私下搜索我的列表{1}}?

例如,如果我可以访问我的应用程序中的整个列表,我可以使用Linq。我可以将Linq查询传递给方法,并让查询在Bookstore内私下执行吗?

2 个答案:

答案 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();

你可以传递这个数组(或列表),或者把它塞到某个地方。在我看来,我用来选择一些书籍的查询独立于书店,所以我不会将结果存储在商店中。