Захват «этого» в Nancy Lambda Capture

#c# #lambda #nancy

#c# #лямбда #nancy

Вопрос:

У меня есть модуль Nancy, который выглядит примерно так

 public class Configurer : NancyModule
{
    private Settings mSettings;

    public Configurer()
    {
        mSettings = new Settings();

        Get["/"] = parameters =>
        {
            // Do something with mSettings here
            mSettings.Name = new string("blah");
            // and then return a response
            return Response.AsJson<Settings>(mSettings);.
        };
    }
}
  

Проблема, с которой я сталкиваюсь, заключается в том, что mSettings всегда null (я предполагаю, потому что я не захватываю this при закрытии lamdba. Я пытался передать это в замыкании, но это не работает). Я также пытался использовать динамический словарь paramaters, но это также не удалось. Возможно ли использовать переменные-члены в модуле nancy, и если да, то как это можно сделать? Вероятно, я упускаю что-то очевидное!

Никаких исключений, касающихся создания настроек и т.д., не генерируется, и я могу использовать это в другом месте класса, только не в лямбдах. Класс также потокобезопасен, я просто не добавил его в приведенный выше пример.

Комментарии:

1. Это единственный раз, когда вы присваиваете значение mSettings полю?

2. @Dirk В реальном коде mSettings действительно считывается только в GET, его настройки заполняются в другом месте, однако доступ к ним осуществляется в других местах класса, и значения соответствуют ожидаемым. Класс потокобезопасен, поэтому, насколько я могу судить, это не гонка данных. Любая переменная-член класса имеет значение null или по умолчанию, когда я пытаюсь получить доступ из GET. Следовательно, почему я предполагаю, что это связано с захватом ‘this’

3. @BenJ Не уверен, как это поможет. Приведенный выше сценарий наивен в том смысле, что он создает локальную копию объекта. Реальный код собирает информацию из другого места в конструкторе, а затем создает копию объекта. Поэтому я не могу передать настройки в качестве аргумента, поскольку параметры участника равны нулю (согласно получению)

4. С захватом проблем нет mSettings . Если это находится null внутри лямбда-выражения, то ему либо никогда не присваивалось значение, либо null ему было присвоено. Вы могли бы проверить, случайно ли вы присвоили ему другое значение, создав поле readonly , таким образом, только конструктор может записывать в него, и вы получите ошибки времени компиляции, если другие методы попытаются это сделать.

5. @YuvalItzchakov Я выяснил, что модули Nancy реконструируются при каждом вызове, т. Е. они не могут сохранять информацию о состоянии. Мне придется поддерживать состояние где-то в другом месте и вызывать его при необходимости. В любом случае спасибо за помощь

Ответ №1:

Оказывается, что при каждом вызове маршрута Nancy (GET и т.д.) Создается новая версия модуля Nancy. Следовательно, время жизни только столько, сколько этот единственный вызов. Это означает, что любые переменные-члены должны быть сконструированы в конструкторе до определения маршрутов Nancy.

Недостатком этого является то, что вы не можете изменять или сохранять состояние в другом месте класса. Поэтому необходимо сохранить информацию о состоянии в другом месте и предоставить интерфейс для извлечения ее из модуля Nancy.

Приведенный выше пример работал бы так, как ожидалось (следовательно, не лучший пример), однако в моем реальном варианте использования mSettings был заполнен в другом месте класса другим методом и считывался только в маршрутах Nancy, к этому времени состояние становится недопустимым.