получить доступ к лямбда-выражению вне ограничивающей области - PullRequest
2 голосов
/ 21 декабря 2009

У меня есть следующий фрагмент тестового кода, и я хочу получить доступ к переменной результата вне лямбда-выражения. Очевидно, это не работает, так как результат всегда нулевой? Я немного погуглил, но, похоже, запутался. Какие у меня варианты?

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 ]

4 голосов
/ 21 декабря 2009

Переменная результата определенно должна быть доступна вне области видимости лямбды. Это основная особенность лямбды (или анонимных делегатов в этом отношении, лямбды - просто синтаксический сахар для анонимных делегатов), называемая «лексическим закрытием». (Подробнее см. 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 запускает лямбду в фоновом потоке? В этом случае, возможно, лямбда еще не запущена к тому времени, когда вы получите доступ к ее значению на следующей строке.
0 голосов
/ 21 декабря 2009

Попробуйте это ..

   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;
0 голосов
/ 21 декабря 2009

Так как до запуска вашей лямбды он равен нулю, вы уверены, что код внутри лямбды выполняется?

Существуют ли другие переменные результата во внешней области, и вы пытаетесь получить доступ к переменной внешней области, но лямбда относится к внутренней области действия?

Примерно так:

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 не является синхронным, может возникнуть проблема с синхронизацией.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...