Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 懒惰问题_C#_Linq - Fatal编程技术网

C# 懒惰问题

C# 懒惰问题,c#,linq,C#,Linq,在C LINQ、IEnumerable、IQueryable……中,设计应用程序的常用方法是什么 现在,我通常尝试使用yield-return和LINQ查询使每个查询尽可能地懒惰,但在运行时,这通常会导致过于懒惰的行为,当每个查询从一开始就被构建时,显然会导致严重的视觉性能下降 我通常的做法是将ToList投影操作符放在某个地方以缓存数据,但我怀疑这种方法可能不正确 从一开始设计这类应用程序的合适/常用方法是什么?一些随机想法-因为问题本身的定义很松散: 只有当结果可能不被使用时,Lazy才是好

在C LINQ、IEnumerable、IQueryable……中,设计应用程序的常用方法是什么

现在,我通常尝试使用yield-return和LINQ查询使每个查询尽可能地懒惰,但在运行时,这通常会导致过于懒惰的行为,当每个查询从一开始就被构建时,显然会导致严重的视觉性能下降

我通常的做法是将ToList投影操作符放在某个地方以缓存数据,但我怀疑这种方法可能不正确


从一开始设计这类应用程序的合适/常用方法是什么?

一些随机想法-因为问题本身的定义很松散:

只有当结果可能不被使用时,Lazy才是好的,因此只有在需要时才加载。然而,大多数操作都需要加载数据,因此从这个角度来看,惰性是不好的。 懒惰会导致棘手的问题。我们已经在ORMs的数据上下文中看到了这一切 说到我,懒惰是好的
如果您需要缓存特定的数据序列,请在该序列上调用一个聚合运算符ToList、ToArray等。否则,只需使用惰性评估


围绕数据构建代码。哪些数据是不稳定的,每次都需要刷新?使用延迟计算,不缓存。哪些数据是相对静态的,只需要拉取一次?将数据缓存在内存中,这样您就不会不必要地提取数据。

这是一个相当广泛的问题,不幸的是,您会经常听到这一点:这取决于具体情况。延迟加载是伟大的,直到它不是

通常,如果反复使用相同的IEnumerables,最好将它们缓存为列表


但无论哪种方式,打电话的人都很少知道这一点。也就是说,如果您从存储库或其他地方获取IEnumerables,最好让存储库完成它的工作。它可能会在内部将其缓存为一个列表,或者每次都会将其建立起来。如果您的呼叫者试图变得太聪明,他们可能会错过数据的更改等。

我建议在返回DTO之前在您的DAL中做一个收费列表

public IList<UserDTO> GetUsers()
{
  using (var db = new DbContext())
  {
    return (from u in db.tblUsers
           select new UserDTO()
           {
               Name = u.Name
           }).ToList();
  }
}

在上面的示例中,您必须在DbContext作用域结束之前创建一个ToList。

我发现将每个IEnumerable分类为三个类别中的一个很有用

快速的-例如列表和数组 缓慢的-例如数据库查询或繁重的计算 非确定性的-例如list.Selectx=>new{…} 对于类别1,我倾向于在适当的时候保留具体类型,数组或IList等。 对于类别3,最好在方法中保持局部性,以避免难以发现的bug。
然后,我们有第2类,和往常一样,在优化性能时,首先测量以找到瓶颈。

延迟执行和使用.ToList缓存所有项目不是唯一的选项。第三个选项是在使用惰性列表进行迭代时缓存项

执行仍被延迟,但所有项目仅产生一次。这是如何工作的一个示例:

public class LazyListTest
{
    private int _count = 0;

    public void Test()
    {
        var numbers = Enumerable.Range(1, 40);
        var numbersQuery = numbers.Select(GetElement).ToLazyList(); // Cache lazy
        var total = numbersQuery.Take(3)
            .Concat(numbersQuery.Take(10))
            .Concat(numbersQuery.Take(3))
            .Sum();
        Console.WriteLine(_count);
    }

    private int GetElement(int value)
    {
        _count++;
        // Some slow stuff here...
        return value * 100;
    }
}
如果运行测试方法,则_计数仅为10。如果不缓存,它将是16,如果使用.ToList,它将是40


一个例子。

天哪!我有一个公吨的代码,看起来几乎和这个一样