潜意识中知道这是IEnumerable的延迟特性造成的,但是硬要条条框框地从原理上解释还真发现自己不行,所以来问问高手们了,同时我想也可以作为一个较为典型的问题,供使用着LINQ的开发者注意一下
直接看题目吧:
首先有一个MyClass类,代码如下

public class MyClass
{
    private int i = 0;

    public MyClass(int i)
    {
        this.i = i;
    }

    public void MethodA()
    {
        i++;
    }

    public void MethodB()
    {
        Console.WriteLine(i);
    }
}

接着在Main函数中用两种方式返回一个MyClass的集合,分别是GetEnumerable和GetList

private static IEnumerable<MyClass> GetEnumerable()
{
    return
        intArray
        .Select(i => new MyClass(i))
        .AsEnumerable();
}

private static IEnumerable<MyClass> GetList()
{
    return
        intArray
        .Select(i => new MyClass(i))
        .ToList();
}

两个方法唯一的区别就在于,一个用了AsEnumerable,一个用了ToList,这里的intArray是早选定义好的private statice int[] intArray = new int[] { 1, 2, 3 };

然后调用如下

public static void Main(string[] args)
{
    //第一种情况,使用Enumerable
    IEnumerable<MyClass> ms = GetEnumerable();
    Console.WriteLine("第一种情况:");
    foreach (MyClass m in ms)
    {
        m.MethodA();
    }
    foreach (MyClass m in ms)
    {
        m.MethodB();
    }

    //第二种情况,虽然ms还是IEnumberable,但事实上对象是个List
    ms = GetList();
    Console.WriteLine("第二种情况:");
    foreach (MyClass m in ms)
    {
        m.MethodA();
    }
    foreach (MyClass m in ms)
    {
        m.MethodB();
    }

    Console.Read();
}

对于每一种情况,都先执行MethodA使内部的i加上1,然后执行MethodB输出i
对于第二种情况,输出的是预期的2, 3, 4
而对于第一种情况,很遗憾,输出的是1, 2, 3

根据单步调试的结果, 事实上返回AsEnumerable()时,那个Select(i => new MyClass(i))每次foreach都要执行

还请高手说下原理,谢谢~

转载于:https://www.cnblogs.com/GrayZhang/archive/2008/06/12/1218631.html

使用LINQ遇到的问题,请高手解答下原理相关推荐

  1. 怎么输出链表长度C语言,下面程序输出结果不,如输出的链表长度结果不对,不知有关问题在哪里。请高手看下...

    当前位置:我的异常网» C语言 » 下面程序输出结果不,如输出的链表长度结果不对,不 下面程序输出结果不,如输出的链表长度结果不对,不知有关问题在哪里.请高手看下 www.myexceptions.n ...

  2. 两路音频合成一路电路_请高手指点下:两路模拟音频信号怎么样才能合成一路再通过喇叭输出...

    请高手指点下:两路模拟音频信号怎么样才能合成一路再通过喇叭输出 nino61 Post at 2008/3/31 9:56:16 小弟,刚接触这方面的知识,不太懂,查了好多资料都没有收获, 希望好心人 ...

  3. c语言简单收银系统程序编码,我有个C语言编写的超市收银系统,请高手修改下,帮做流程图,可追加分...

    我有个C语言编写的超市收银系统,请高手修改下,帮做流程图,可追加分0 #includestruct goods{ char no[8];3char name[20];  float price;  i ...

  4. 在c语言中下面的运算符中优先级最高的是,C语言习题请高手解答急急急1.下列运算符中优先级最高的运算符 爱问知识人...

    1.下列运算符中优先级最高的运算符是 A:! B: % C:-= D: && 2.下列运算符中优先级最低的运算符是 A:| B:!= C:=Y)&&(Y>=Z) ...

  5. 远程主机强迫关闭了一个现有的连接。请高手解答?

    远程主机强迫关闭了一个现有的连接. 说明: 执行当前 Web 请求期间,出现未处理的异常.请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息. 异常详细信息: System.Net ...

  6. php mysql 快餐_用PHP+MYSQL做一个简单的点餐系统的后台,初学者. 请高手指点下如何实现后台添加菜名 餐馆 价格...

    展开全部 "  name="cm"  placeholder="菜名" type="text" /> "  nam ...

  7. ucosii操作系统和linux,请高手介绍下uCOSII和Linux的差异?

    区别:ucos有执行效率高.占用空间小.实时性和可扩展性强等特点,linux有稳定性.强大网络功能和出色的文件系统等优点. 联系:是两种性能优良源码公开且被广泛应用的的免费嵌入式操作系统,可以作为研究 ...

  8. catia装配体怎么把零件旋转180度,CATIA装配中怎样旋转复制单个零件,请高手赐教下啊!谢谢了!...

    味精中的主要成分是谷氨酸钠,它味道鲜美,可用以调味,但却没有什么营养,所以说味精只是一种比较纯粹的调味剂.而鸡精中尽管也含有比重很高的味精成分,但是其中还含有多种营养物质.优质的鸡精是用新鲜的鸡肉.鸡 ...

  9. 安卓软件错误log_关于android程序的log错误信息的问题,请明白人看下吧,我是初学者,新建的android项目,一个代码都没改过...

    log信息:07-0801:55:43.985:ERROR/vold(27):Erroropeningswitchnamepath'/sys/class/switch/test'(Nosuchfile ...

最新文章

  1. 如果你去小公司带技术团队,可能需要做的事情
  2. 使用tolua++编译pkg,从而创建自定义类让Lua脚本使用
  3. kickstart自动化安装
  4. 用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)
  5. 周报措辞规范(周报规范用语、不规范用语)
  6. 为什么晚上咳嗽很厉害
  7. Perl 之 use(), require(), do(), %INC and @INC
  8. 前端学习(1254):Vue前后端交互方式
  9. Java 并发之 FutureTask 的基本使用
  10. 如何更好地刷题?谈谈我的一点看法
  11. 逆向libbaiduprotect(二)
  12. Ps2021教程,如何在photoshop中调整建筑物透视效果?
  13. html标签种类很多,为什么不都用div?
  14. 经典CNN之:VGGNet
  15. 小程序毕设作品之微信小程序点餐系统毕业设计(6)开题答辩PPT
  16. pano2vr怎么制作漫游_Pano2VR如何制作全景图?全景图如何添加热点?
  17. DTM测试里无线Modem应该选哪种MCU?
  18. 迅雷9解决php文件,迅雷9的这些优化 你必须要知道
  19. windows下自动切换并连接wifi热点
  20. np和tensor转换

热门文章

  1. 减少HTTP请求的方法
  2. react-移动端项目
  3. LeetCode--81. 搜索旋转排序数组Ⅱ(遍历法,二分法)
  4. NG ChangeDetectorRef(变更检测)
  5. 随讲单片机与Arduino
  6. Tomcat Connector
  7. AIX学习笔记-第一天简介
  8. mysql数据库索引调优
  9. 小程序开发中遇到的问题
  10. Octave 作图 无响应