代码之家  ›  专栏  ›  技术社区  ›  Rippo

访问封闭范围之外的lambda表达式

  •  2
  • Rippo  · 技术社区  · 15 年前

    我有下面的一段测试代码,希望访问封闭lambda表达式之外的变量结果。显然这不起作用,因为结果总是空的?我在谷歌上搜索了一下,但似乎把自己弄糊涂了。我有什么选择?

    RequestResult result = null;
    RunSession(session =>
    {
        result = session.ProcessRequest("~/Services/GetToken");
    });
    result //is null outside the lambda
    

    编辑-更多信息如下

    runsession方法具有以下签名

    protected static void RunSession(Action<BrowsingSession> script)
    
    3 回复  |  直到 15 年前
        1
  •  4
  •   Geert Baeyaert    15 年前

    结果变量应该可以从lambda范围之外访问。这是lambda的一个核心特性(或者说匿名委托,lambda只是匿名委托的语法甜头),称之为“词汇闭包”。(有关详细信息,请参阅 http://msdn.microsoft.com/en-us/magazine/cc163362.aspx#S6 )

    为了验证,我重写了您的代码,只使用了更基本的类型。

    class Program
    {
        private static void Main(string[] args)
        {
            string result = null;
            DoSomething(number => result = number.ToString());
            Console.WriteLine(result);
        }
    
        private static void DoSomething(Action<int> func)
        {
            func(10);
        }
    }
    

    这张照片印了10张,所以我们现在知道应该可以了。

    现在,您的代码可能有什么问题?

    1. session.processRequest功能是否正常?您确定它不返回空值吗?
    2. 也许您的runsession在后台线程上运行lambda?在这种情况下,可能是lambda在您访问下一行的值时尚未运行。
        2
  •  0
  •   Skurmedel    15 年前

    因为在LAMBDA运行之前它是空的,您确定LAMBDA内部的代码是否被执行了?

    外部作用域中是否还有其他结果变量,您试图访问外部作用域变量,但lambda引用了内部作用域?

    像这样:

    class Example
    {
        private ResultSet result;
    
        public Method1()
        {
            ResultSet result = null;
            RunSession(session => { result = ... });
        }
    
        public Method2()
        {
            // Something wrong here Bob. All our robots keep self-destructing!
            if (result == null)
                SelfDestruct(); // Always called
            else
            {
                // ...
            }
        }
    
        public static void Main(string[] args)
        {
            Method1();
            Method2();
        }
    }
    

    如果runsession不同步,则可能存在计时问题。

        3
  •  0
  •   RameshVel    15 年前

    试试这个…

       protected static void RunSession(Action<BrowsingSession> script)
       {
           script(urSessionVariableGoeshere);
       }
    

       RequestResult result = null;
       Action<sessionTyep> Runn = (session =>{  
             result = session.ProcessRequest("~/Services/GetToken");
       }
       );
       RunSession(Runn);
       var res = result;