1

下面的代码有效,但我想使用 yield 或更改算法来优化代码。

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    var bookAndAuthorList = new List<Book>();
    List<Author> AuthorNameList = getAuthorName(keyword);
    foreach (var author in AuthorNameList)
    {
        XmlNode booksNames = getBook(author);
        XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

        var bookNameList = (
            from x1 in XDOCbooksNames.Descendants("Books")
            select x1.Elements("book").Select(g => g.Attribute("name").Value))
            .ToList();
        foreach (var bookName in bookNameList)
        {
            bookAndAuthorList.Add(new Book()
            {
                authorName = author.authorName,
                bookName = bookName
            });
        }
    }
    return bookAndAuthorList;
}

public class Book
{
    public string authorName { get; set; }
    public string bookName { get; set; }
}
4

4 回答 4

9

鲁本斯和卢克的回答正确地解释了产量的使用。

但是,这对我来说似乎很可疑。

XmlNode booksNames = getBook(author);
XDocument XDOCbooksNames = XDocument.Parse(booksNames.OuterXml);

您将 XML 转换为字符串,然后再次解析它,只是因为您想将其从 DOM 节点转换为 Xml.Linq 节点。如果您在谈论优化,那么这比创建额外列表效率低得多。

于 2009-12-29T23:40:28.663 回答
6

作为快速获胜,您可以删除.ToList()呼叫。您所做的只是枚举项目,因此无需这样做。同样,不需要创建 bookAndAutherList。

最终,我认为您可以将其简化为:

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    return from author in getAuthorName(keyword)
           let book = getBook(author)
           from xmlBook in XDocument.Parse(book.OuterXml).Descendants("Books")
           select new Book
           {
               authorName = author.AuthorName,
               bookName = xmlBook.Attribute("name").Value
           };
}
于 2009-12-29T23:33:31.877 回答
1

不确定你会得到多少“优化”。当您经常中断使用正在生成的枚举时,最好使用产量,这样您就不会进行不必要的计算。但这里有:

这是未经测试的。

public IEnumerable<Book> GetAuthorWithBookName(string keyword)
{
    foreach (var author in getAuthorName(keyword))
    {
        XDocument XDOCbooksNames = XDocument.Parse(getBook(author).OuterXml);

        var bookNameList = from x1 in XDOCbooksNames.Descendants("Books")
                            select x1.Elements("book").Select(g => g.Attribute("name").Value);

        foreach (var bookName in bookNameList)
        {
            yield return new Book()
                {
                    authorName = author.authorName,
                    bookName = bookName
                };
        }
    }
}

我做了什么:

  1. 删除表达式上的 ToList(),它已经返回一个可枚举的。通过将 getAuthorName 合并到 foreach 中删除了一些代码(注意 - 如果可以,请确保函数也可以产生和 ienumerable)
  2. 收益回报而不是添加到列表中
于 2009-12-29T23:25:53.270 回答
0

试试这个:

foreach (var bookName in bookNameList)
{
    yield return new Book()
    {
        authorName = author.authorName,
        bookName = bookName
    };
}

并删除其他return声明。

于 2009-12-29T23:25:36.263 回答