微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

添加到列表会覆盖旧值

如何解决添加到列表会覆盖旧值

我正在编写一个 webscraper 并希望将每个产品(对象 Product)存储在一个 List<Product> list

public static void ScrapeItem(List<string> itemList)
{
    HtmlDocument html = new HtmlDocument();
    ScrapedData data = new ScrapedData();

    LinkedList<Product> list = new LinkedList<Product>();
    Product newProduct = new Product();

    for (int j = 0; j < itemList.Count; j++)
    {
        HtmlRequest req = new HtmlRequest(itemList[j]);
        html = req.StartRequest(html);
        newProduct = data.chooseStrategy(new ConcreteStrategyItemA(html));

        Console.WriteLine("###" + newProduct.Name);
        Console.WriteLine("###" + newProduct.Price);

        Console.WriteLine("------------------------------");

        list.AddLast(newProduct);
        foreach (Product product in list)
        {
            Console.WriteLine(product.Name);
            Console.WriteLine(product.Price);
        }
    }

newProduct 上的 WriteLine 工作正常,因此 foreach 循环中的每次迭代都包含不同的产品(ProductA、ProductB、ProductC)。但是当我在每次迭代中将此对象存储到列表中时,列表最后只包含 ProductC。

因此该列表的末尾应包含以下内容

index 0: ProductA 
index 1: ProductB 
index 2: ProductC 

但它是这样的:

index 0: ProductC 
index 1: ProductC 
index 2: ProductC 

我对 C# 比较陌生,但在 Java 中,这段代码应该可以工作。

编辑: ChooseStrategy 看起来像这样:

 public Product chooseStrategy(ScraperStrategy ConcreteStrategy)
        {
            return ConcreteStrategy.startScraping(product);
        }

startScraping 看起来像这样:

public override Product startScraping(Product product)
        {
            Console.WriteLine("ConcreteStrategyitemA");

            product.Name = this._html.DocumentNode.SelectNodes("/html/body/div[6]/section/div/div/div/div/form/div/div[2]/h1")[0].InnerText; // Name xPath

            product.Price = this._html.DocumentNode.SelectNodes("/html/body/div[6]/section/div/div/div/div/form/div/div[3]/div[3]/span[2]")[0].InnerText; // Price xPath

            return product;
        }

解决方法

您的问题似乎与 this one 类似。如果您真的不想使用 LinkedList,请不要使用 LinkedList。而是使用 .net 的基本列表

List<Product>

使用 .Add(item) 您可以为一项附加您的列表,这似乎是此处所需的行为。

编辑1: 其他方法

public static void ScrapeMindfactory(List<string> mindfactoryList)
{
HtmlDocument html = new HtmlDocument();
ScrapedData data = new ScrapedData();
LinkedList<Product> list = new LinkedList<Product>();

for (int j = 0; j < mindfactoryList.Count; j++)
{
    HtmlRequest req = new HtmlRequest(mindfactoryList[j]);
    html = req.StartRequest(html);
    var newProduct = data.chooseStrategy(new ConcreteStrategyMindfactory(html));

    Console.WriteLine("###" + newProduct.Name);
    Console.WriteLine("###" + newProduct.Price);

    Console.WriteLine("------------------------------");

    list.AddLast(newProduct);
    foreach (Product product in list)
    {
        Console.WriteLine(product.Name);
        Console.WriteLine(product.Price);
    }
}

在选择策略()中:

    public Product chooseStrategy(ScraperStrategy ConcreteStrategy)
        {
            return ConcreteStrategy.startScraping(new Product());
        }

这样就行了。

chooseStrategy 中对产品的引用始终相同,因此 startScraping 需要 (new Product()) 作为参数。 @canton7

,

解决这个问题

public Product chooseStrategy(ScraperStrategy ConcreteStrategy)
        {
           var product= new  Product();
            return ConcreteStrategy.startScraping(product);
        }

甚至更好


public override Product startScraping()
        {
            Console.WriteLine("ConcreteStateMindfactory");

         var  product = new Product {

        Name = this._html.DocumentNode.SelectNodes("/html/body/div[6]/section/div/div/div/div/form/div/div[2]/h1")[0].InnerText,// Name xPath

           Price = this._html.DocumentNode.SelectNodes("/html/body/div[6]/section/div/div/div/div/form/div/div[3]/div[3]/span[2]")[0].InnerText // Price xPath

}

            return product;
        }

public Product chooseStrategy(ScraperStrategy ConcreteStrategy)
        {
           
            return ConcreteStrategy.startScraping();
        }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。