zoukankan      html  css  js  c++  java
  • 常见的Lambda表达式引起的闭包问题

    以下代码的原意是想找出list中满足Name字段包含t, Remark字段包含mark的数据

    代码
    //构造的搜索条件 希望Name包含t remark中包含mark中的文本
    Dictionary<string, string> forms = new Dictionary<string, string>();
    forms.Add(
    "Name", "t");
    forms.Add(
    "Remark", "mark");

    //构造一些数据 理论上全部数据都应该满足上面的那个条件 (忽略大小写)
    List<UserInformation> list = new List<UserInformation>() {
    new UserInformation(){Name ="Test1", Remark="Remark1"},
    new UserInformation(){Name ="Test2", Remark="Remark2"},
    new UserInformation(){Name ="Test3", Remark="Remark3"},
    };

    var lambda
    = list.AsQueryable();
    foreach (string key in forms.Keys)
    {
    string val = forms[key];
    if (key == "Name")
    lambda
    = lambda.Where(p => p.Name.Contains(val));//原意是 在条件是Name的时候 对Name字段做过滤
    if (key == "Remark")
    lambda
    = lambda.Where(p => p.Remark.Contains(val));//原意是 在条件是Remark的时候 对Remark字段做过滤
    }

    var data
    = lambda.ToList();//大家可以注意到结果是0条
    var data2 = list.AsQueryable().Where(p => p.Name.Contains(forms["Name"])).Where(p => p.Remark.Contains(forms["Remark"])).ToList();//这个的结果是3条

    不过实际情况是data中间一条记录都没有

    而hardcode算出来的data2中有3条记录

    原因如下:

      这个lambda表达式 Where(p=>p.Name.Contains(val))  , 实际上只是保留了一个指向函数外部的val的引用 , 他这个时候并没有把val的真实的值拷贝进来

      真正去读取val值的时候是 lambda.ToList() 这个时候才真正执行lambda表达式取数据,过滤数据 ,也是这个时候才去读取val的值

      而在foreach的第二次操作的时候 val的值被覆盖mark了 那么就造成了 原来的Where(p=>p.Name.Contains(val))  变成了 Where(p=>p.Name.Contains("mark"))  

      注意那个值是mark而不是t

      如果我们把三条数据的Name都改成markdafafafadsf 之类的值 那么再次计算data的数据就会变成三条, 大家可以自己弄一下试试,

    作用域:

      本来val是一个临时变量,他的生命周期应该在foreach结束以后就结束了

      但是 由于他被闭包引用,那么val的生命周期延长到引用对象的生命周期(那个lambda不死....val也就会一直活着)

      

  • 相关阅读:
    Java Web 网络留言板2 JDBC数据源 (连接池技术)
    Java Web 网络留言板3 CommonsDbUtils
    Java Web ConnectionPool (连接池技术)
    Java Web 网络留言板
    Java Web JDBC数据源
    Java Web CommonsUtils (数据库连接方法)
    Servlet 起源
    Hibernate EntityManager
    Hibernate Annotation (Hibernate 注解)
    wpf控件设计时支持(1)
  • 原文地址:https://www.cnblogs.com/PurpleTide/p/1929735.html
Copyright © 2011-2022 走看看