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

发布于 2024-08-15 17:39:18 字数 437 浏览 3 评论 0原文

我有以下一段测试代码,并且想要访问封闭 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)

I have the following piece of test code and want to access the variable result outside the enclosing lambda expression. Obviously this does not work as result is always null? I have Googled around a bit but seem to got myself more confused. What are my options?

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

EDIT - more information below

The RunSession method has the following signature

protected static void RunSession(Action<BrowsingSession> script)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北音执念 2024-08-22 17:39:18

结果变量绝对应该可以从 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 函数有效吗?你确定它不会返回 null 吗?
  2. 也许您的 RunSession 在后台线程上运行 lambda?在这种情况下,当您在下一行访问 lambda 值时,lambda 可能尚未运行。

The result variable should definitely be accessible from outside the scope of the lambda. That's a core feature of lambdas (or anonymous delegates for that matter, lambdas are just syntactic sugar for anonymous delegates), called a "lexical closure". (For more info, see http://msdn.microsoft.com/en-us/magazine/cc163362.aspx#S6)

Just to verify, I rewrote your code, only using more basic types.

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);
    }
}

This prints 10, so we now know that this should work.

Now what could be the problem with your code?

  1. Does the session.ProcessRequest function work? Are your sure it does not return null?
  2. Perhaps your RunSession runs the lambda on a background thread? In that case, it could be that the lambda has not yet run by the time you access its value on the next line.
2024-08-22 17:39:18

由于在您的 lambda 运行之前它为 null,因此您确定 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 不同步,您可能会遇到计时问题。

Since it's null until your lambda runs, are you sure that the code inside the lambda is executed?

Are there other result variables in a outer scope, and you are trying to access the outer scope variable but the lambda refers to the inner scoped?

Something like this:

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();
    }
}

If RunSession is not synchronous, you might have a timing issue.

天赋异禀 2024-08-22 17:39:18

试试这个..

   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;

Try this..

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

And

   RequestResult result = null;
   Action<sessionTyep> Runn = (session =>{  
         result = session.ProcessRequest("~/Services/GetToken");
   }
   );
   RunSession(Runn);
   var res = result;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文