Препятствуйте тому, чтобы.NET “сняла” локальные переменные

Вы также можете использовать агрегат:

db.accommodations.aggregate(
[
     {$project: {_id:1, name:1, zipcode:1, 
                 size_of_name: {$size: "$name"}
                }
     },
     {$match: {"size_of_name": {$gt: 1}}}
])

// вы добавляете «size_of_name» для переноса документа и используете его для фильтрации размера имени

7
задан Brownie 21 September 2008 в 08:24
поделиться

9 ответов

Я вижу базовую проблему теперь. Это глубже, чем я сначала думал. В основном решение состоит в том, чтобы изменить дерево выражений прежде, чем сериализировать его путем замены всех поддеревьев, которые не зависят от параметров с постоянными узлами. Это, по-видимому, называют "funcletization". Существует объяснение его здесь.

8
ответ дан 7 December 2019 в 05:35
поделиться

Просто сделайте другое закрытие...

Скажите, что-то как:

var prepend = "OLD:";

Func<string, Func<string, string>> makePrepender = x => y => (x + y);
Func<string, string> oldPrepend = makePrepender(prepend);

prepend = "NEW:";

Console.WriteLine(oldPrepend("Brownie"));

Havn't протестировал его все же, поскольку у меня нет доступа к VS в данный момент, но обычно, это - то, как я решаю такую проблему.

2
ответ дан 7 December 2019 в 05:35
поделиться

Я получаю проблему теперь: лямбда относится к содержанию класса, который не мог бы быть сериализуемым. Затем сделайте что-то вроде этого:

public void static Func<string, string> MakePrependAction(String prefix){
    return (x => prefix + x);
}

(Отметьте статическое ключевое слово.) Затем лямбда не должна ссылаться на содержание класса.

0
ответ дан 7 December 2019 в 05:35
поделиться

Лямбды автоматически 'сосут' в локальных переменных, я боюсь, что это просто, как они работают по определению.

1
ответ дан 7 December 2019 в 05:35
поделиться

Это - довольно типичная проблема т.е. переменные, изменяемые закрытием неумышленно - далекое простое решение состоит в том, чтобы только пойти:

string prefix = "OLD:";
var actionPrefix = prefix;
Func<string, string> prependAction = (x => actionPrefix + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));

При использовании resharper, он на самом деле определит места в коде, где Вы подвергаетесь риску вызывать неожиданные побочные эффекты, такие как это - поэтому, если файл является "полностью зеленым" Ваш код, должен быть в порядке.

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

Func<string, string> prependAction = (x => ~prefix + x);

Где некоторый префиксный оператор заставил бы значение переменной быть оцененным до построения анонимного делегата/функции.

0
ответ дан 7 December 2019 в 05:35
поделиться

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

В зависимости от того, что Вы на самом деле пытаетесь сделать (я не могу вполне решить из Вашего сообщения), решение состояло бы в том, чтобы переместить несериализуемую часть лямбды снаружи.

Например, вместо:

NonSerializable nonSerializable = new NonSerializable();
Func<string, string> prependAction = (x => nonSerializable.ToString() + x);

использование:

NonSerializable nonSerializable = new NonSerializable();
string prefix = nonSerializable.ToString();
Func<string, string> prependAction = (x => prefix + x);
0
ответ дан 7 December 2019 в 05:35
поделиться

Что относительно этого

string prefix = "OLD:";
string _prefix=prefix;
Func<string, string> prependAction = (x => _prefix + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));
-1
ответ дан 7 December 2019 в 05:35
поделиться

Как насчет:

string prefix = "OLD:";
string prefixCopy = prefix;
Func<string, string> prependAction = (x => prefixCopy + x);
prefix = "NEW:";
Console.WriteLine(prependAction("brownie"));

?

-1
ответ дан 7 December 2019 в 05:35
поделиться

Ну, если мы собираемся говорить о "проблемах" здесь, лямбды прибывают из мира функционального программирования, и на языке чисто функционального программирования, нет никаких присвоений и таким образом, Ваша проблема никогда не возникала бы, потому что значение префикса никогда не могло изменяться. Я понимаю, что C# думает, что здорово импортировать идеи из функциональных программ (потому что FP прохладен!), но очень трудно сделать это симпатичным, потому что C# и всегда будет императивным языком программирования.

-1
ответ дан 7 December 2019 в 05:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: