ASP.NET MVC 2中的LazyList <T> vs System.Lazy <List <T >>?

Pet*_*ron 12 c# lazy-loading asp.net-4.0 lazylist asp.net-mvc-2

在Rob Conery的Storefront系列中,Rob广泛使用该LazyList<..>构造来从中提取数据IQueryables.

  • 这与System.Lazy<...>.NET 4.0(现在可能更早)中现有的构造有何不同?

更深入的基于DoctaJones的伟大答案:

  1. 如果我想IQueryable作为一个操作,你会推荐一个List<T>吗?
    我假设Lazy<T>现在在框架中,对未来的支持和可维护性来说是一个更安全的赌注?
  2. 如果我想使用强类型而不是anonymous(var)类型,以下语句在功能上是否相同?
    • Lazy<List<Products>> Products = new Lazy<List<Product>>();
    • LazyList<Product> = new LazyList<Product>();

Rei*_*ica 17

所述LasyList <T>只适用于一个的IQueryable <T>源.它是IList <T>的一个实现,它通过使用指定的IQueryable <T>的所有结果填充私有List来工作.首次访问任何IList <T>成员时,都会进行初始化.

示例用法是

var myList = new LazyList(products.Where(p => p.Name.StartsWith("T"));
//initialization occurs here
Console.Write(myList.Count);
Run Code Online (Sandbox Code Playgroud)

所述System.Lazy <T>类适用于任何类型的,并且不限于IQueryable的<T>.第一次访问Lazy <T> .Value属性时会发生延迟初始化.

示例用法是

var lazyString = new Lazy(() => "Hello world");
//initialization occurs here
Console.Write(lazyString.Value);
Run Code Online (Sandbox Code Playgroud)

我们可以重写LazyList <T>示例以使用Lazy <T>,如下所示:

var myList = new Lazy(() => products.Where(p => p.Name.StartsWith("T").ToList());
//initialization occurs here
Console.Write(myList.Value.Count);
Run Code Online (Sandbox Code Playgroud)

简而言之: LazyList <T>仅适用于IQueryable <T>,Lazy <T>适用于任何类型.

LazyList <T>适用于您希望IQueryable <T>的结果为List <T>的特定用例,但您不希望在使用它之前进行评估.


更新以回答扩展的问题:

如果我想将IQueryable作为List <T>操作,你会推荐一个吗?我假设既然Lazy <T>现在处于框架中,那么对于未来的支持和可维护性来说,这是一个更安全的选择吗?

我个人也不会用.如果你有一个IQueryable我会保持它作为一个IQueryable,以最大限度地提高你的灵活性.通过保持IQueryable,您仍然可以访问LINQ to SQL的查询理解(只要上下文仍然存在).

例如,如果在IQueryable上调用.ToList(),则要求LINQ to SQL 从目标表中选择所有列并保存所有结果(这可能非常昂贵,尤其是如果您有数千个结果).这将被翻译成类似"SELECT*FROM MyTable"的内容.

如果在IQueryable上调用.Count(),则要求LINQ to SQL只获取结果数,这将转换为"SELECT COUNT(*)FROM MyTable".这样做比保湿所有结果然后计算它们更有效率,特别是如果你只对这个数字感兴趣的话!

通过在IQueryable LINQ to SQL上使用.Where(),可以将条件添加到SQL查询中的WHERE子句中.这意味着您只会从您感兴趣的SQL中提取数据,而不是保留您无意使用的结果.

你可以看到,通过保持IQueryable,你可以让自己更灵活.在大多数情况下,它会比为整个结果集保湿提供更好的性能.

如果我想使用强类型而不是匿名(var)类型,以下语句在功能上是否相同?

Lazy<List<Product>> products = new Lazy<List<Product>>(); 
LazyList<Product> products = new LazyList<Product>();
Run Code Online (Sandbox Code Playgroud)

我认为你的匿名打字与隐式打字相混淆.使用var关键字声明的变量是隐式类型,以匹配分配给它的类型.它强类型的,因此在初始分配后不能更改.

这两个陈述在功能上并不相同.LazyList <Product>是IList <Product>,而Lazy <List <Product >>是包含List <Product>的包装器.因为你对懒惰的评估列表特别感兴趣,所以我认为LazyList 可能更适合你的目的.

你应该问问自己是否真的需要一个真正的产品清单.如果没有令人信服的理由有一个实际的List我会坚持使用IQueryable.