LazyList <t> vs System.Lazy <list <t>&gt;在ASP.NET MVC 2中?</list <t> </t>

时间:2010-04-22 10:31:39

标签: asp.net-mvc-2 lazy-loading asp.net-4.0 lazylist

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

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

更多深度基于DoctaJones的好答案:

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

1 个答案:

答案 0 :(得分:17)

LasyList<T>仅适用于IQueryable<T>来源。它是IList<T>的一个实现,通过使用指定的IQueryable&lt; T&gt;的所有结果填充私有List来工作。初次访问任何IList&lt; T&gt;时进行初始化。成员。

示例用法是

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

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

示例用法是

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

我们可以重写LazyList&lt; T&gt;使用Lazy&lt; T&gt;的示例如下:

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

简而言之: LazyList&lt; T&gt;仅适用于IQueryable&lt; T&gt;,Lazy&lt; T&gt;适用于任何类型。

LazyList&LT; T&GT;是您想要IQueryable&lt; T&gt;的结果的特定用例。作为列表&lt; T&gt;,但您不希望在使用它之前进行评估。


更新以回答扩展问题:

  

如果我想将IQueryable作为List&lt; T&gt;?操作,你会推荐一个吗?   我假设自从Lazy&lt; T&gt;现在是在框架中,对未来的支持和可维护性来说是一个更安全的选择吗?

我个人也不会使用。如果你有一个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>();

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

这两个陈述在功能上并不相同。 LazyList&lt; Product&gt;是一个IList&lt; Product&gt;,而Lazy&lt; List&lt; Product&gt;&gt;是一个包含List&lt; Product&gt;的包装器。因为你特别感兴趣的是对懒惰的评估列表进行操作,所以我认为LazyList可能可能更适用于你的目的。

您应该问问自己真的是否需要实际的产品列表。如果没有令人信服的理由拥有实际的List我会坚持使用IQueryable。