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

Rubens と Luke による回答は、yield の使用を正しく説明しています。

しかし、これは私には疑わしいように見えます。

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

DOM ノードから Xml.Linq ノードに変換したいという理由だけで、XML を文字列に変換してから再度解析します。最適化について話している場合、これは追加のリストを作成するよりもはるかに非効率的です。

于 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

多くの「最適化」が得られるかどうかはわかりません。不要な計算を行わないように、生成している列挙型を途中で中断することが多い場合は、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. リストに追加する代わりに利回りを返す
于 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 に答える