【问题标题】:LINQ Filtering a List of objectsLINQ 过滤对象列表
【发布时间】:2014-11-13 03:57:17
【问题描述】:

我在内存中有一个 List。它包含我数据库中的所有产品。这保存在缓存中。

根据 QueryString,我需要过滤该产品列表并将转发器绑定到它。

所以我将 LINQ .Where 子句应用于我的列表,但正如您所知,Where 返回 IEnumerable

如果我有

var category = "Beverages";
var filteredProducts = allProducts.Where(p => p.Category = category);

当我调用filteredProducts.ToList() 会发生什么?

注意 allProducts 是一个 List() 并且包含大约 300 个项目。

我猜它会在内存中创建一个新的 List 并从 allProducts 列表中复制相关项目。

过滤后的产品约为。 60 项。

这在性能方面有多糟糕?

编辑:它是一个网络应用程序,所以我们正在谈论假设一次对这个页面的数十个请求,这可能会影响性能。

【问题讨论】:

  • 可能比您编写自己的循环将它们放入列表中更好。顺便说一句,你的问题没有一个明确的答案,它是一种开放式的
  • 60 项....小菜一碟
  • 没关系。就性能而言,您不会注意到 60 或 300。当你达到数百万的规模时,你可能想回顾一下
  • 无论如何它只会复制引用(我假设你有一个类而不是结构)。从记忆的角度来看没有什么风险。
  • 您的评论“我猜它会在内存中创建一个新的 List 并从 allProducts 列表中复制相关项目。”是错的。它不会复制相关项目。它将为您提供一个新列表,其中包含 60 个对原始列表中相同对象的引用。如果您更改这些对象中的某些内容,它们将在两个集合中发生更改。

标签: c# asp.net .net linq


【解决方案1】:

感觉就像为演示目的编写了一些愚蠢的代码。此演示的目的是让您看到在您的IEnumerable 上调用.ToList() 时,只有对象的引用 被复制到新创建的列表中。因此,原始列表和新列表中的基础对象都是相同的。这有两个含义。首先,您的对象没有低效的深层副本。其次,对原始列表中的项目和新列表中的项目所做的更改将影响这两个列表,因为内存中的对象相同。将其放入控制台应用程序以查看输出。

class Program
{
    class Dog
    {            
        public string name { get; set; }
        public bool isAGoodBoy { get; set;}
        public Dog(string name, bool isAGoodBoy)
        {
            this.name = name;
            this.isAGoodBoy = isAGoodBoy;
        }
    }

    static void Main(string[] args)
    {            
        List<Dog> doges = new List<Dog>();
        doges.Add(new Dog("Rufus", true));
        doges.Add(new Dog("Kevin", false)); //chewed furniture
        doges.Add(new Dog("Maximus", true));

        IEnumerable<Dog> goodBoys = doges.Where(doggy => doggy.isAGoodBoy);
        List<Dog> goodBoysList = goodBoys.ToList();
        foreach (var goodBoy in goodBoysList)   //Iterate over NEW list
        {
            goodBoy.isAGoodBoy = false;    //They wouldn't stop barking
        }

        //From original list! You'll see all of these will output 'False'
        Console.WriteLine("Is Rufus good? " + doges[0].isAGoodBoy.ToString());    
        Console.WriteLine("Is Kevin good? " + doges[1].isAGoodBoy.ToString());    
        Console.WriteLine("Is Maximus good? " + doges[2].isAGoodBoy.ToString());    

        Console.ReadLine();

    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 2022-01-06
    • 2021-12-05
    相关资源
    最近更新 更多