使用yield或更改算法优化代码

时间:2009-12-29 23:19:34

标签: c# linq optimization linq-to-xml yield

下面的代码有效,但我想使用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 个答案:

答案 0 :(得分:9)

鲁本斯和卢克的回答正确地解释了收益率的使用。

然而,这看起来很可疑。

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

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

答案 1 :(得分: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
           };
}

答案 2 :(得分:1)

不确定你会得到多少'优化'。当您经常使用正在生成的枚举时,会更好地使用yield,这样您就不会进行不必要的计算。但是这里有:

这是未经测试的。

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(注意 - 如果可以的话,确保函数产生并且也是可以产生的)
  2. 收益率返回而不是添加到列表

答案 3 :(得分:0)

试试这个:

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

删除其他return语句。