zoukankan      html  css  js  c++  java
  • 小记扩展方法的延迟执行

    描述这样一个场景:

    一个程序,执行的时候没有成功连接到数据存储引擎,当源源不断的新增数据要添加到数据存储里的时候就不能正常添加,此时需要一个临时存储方式。 假设先用一个缓存保存,然后当缓存数据量达到一定数量时,就取出这些数据开辟单独线程用其他保存方式进行保存。

     然后看一段模拟代码:

    IList<int> cache = new List<int>();
                
    int i = 0;
                
    while(i<1000)
                {
                    cache.Add(i);
                    i
    ++;
                }
                var temp 
    = cache.Take(100); 
                cache.Clear();
                
    foreach (var p in temp)
                {
                    Console.WriteLine(p);
                }

    这段代码用了 Take<T>() 这个扩展方法, 这里要说的是,要做好从cache里取出前面的N条数据的方法有很多,

    但是如果你这样使用了Take<T>() 方法你就会发现,你的temp里面什么都没有,

    原因在与Take<T>() 是延迟执行的,而在Take<T>() 方法的下句已经执行了cache.clear() 清空了源数据,所有在foreach时候真正取数据的时候cache已经为空了,

    Take<T>()自然就取不到数据了;

    以下摘抄一点MSDN内容供大家参考;


    此方法通过使用延迟执行实现。即时返回值为一个对象,该对象存储执行操作所需的所有信息。只有通过直接调用对象的 GetEnumerator 方法或使用 Visual C# 中的 foreach(或 Visual Basic 中的 For Each)来枚举该对象时,才执行此方法表示的查询。 

    那么,在上面这段示例代码中,如何修改使其得到正确结果呢,请看下面:

     IList<int> cache = new List<int>();
                
    int i = 0;
                
    while (i < 1000)
                {
                    cache.Add(i);
                    i++;
                }
                var temp = cache.Take(100).ToList();
                cache.Clear();
                
    foreach (var p in temp)
                {
                    Console.WriteLine(p);
                }

    很简单,将Take<T>() 的执行结果 ToXXX 一下就可以了,这里有ToList()  ToArray() 等方法都是同样一个道理。

    通过这个小例可以发现在使用Linq带来的便捷的同时,对于扩展方法也需小心使用。

  • 相关阅读:
    浅析CString内部实现机制
    ...sourceannotations.h(142) : error C3094: “repeatable”: 不允许匿名使用
    非MFC项目使用CString及如何打印
    GetTextExtentPoint32--获取字符串在屏幕上长度
    窄字符与宽字符相关的操作
    如何给图片添加黑色边框
    react native
    礼仪 习俗 文化
    职业 行业 2 博客
    读书 文摘 笔记 2 人生的支柱
  • 原文地址:https://www.cnblogs.com/cxwx/p/1867520.html
Copyright © 2011-2022 走看看