Вызывается ли Linq-Query toList(), генерируя копии содержащихся элементов?

Я столкнулся с (для меня) странным поведением. Вот код:

var objects = from i in items
              //some calculations
              select something;

// other calculations

objects.ToList().ForEach(x => {
    //some calculations
    x.Property = "some text"
});

return objects;

Сначала я генерирую IEnumerableЭто запрос к БД, я пропустил детали. Затем я должен сделать другие вычисления и в конце я перебрать свои объекты, чтобы установить дополнительный параметр. Запуск этого кода, как только IEnumerable объекты возвращаются, их Property не установлен.

В противном случае, если я перееду ToList() в последующем выражении Linq Property установлено:

var objects = (from i in items
              //some calculations
              select something).ToList();

// other calculations

objects.ForEach(x => {
    //some calculations
    x.Property = "some text"
});

return objects;

Насколько я знаю, объекты не копируются, а ссылаются... верно? Что за очевидными кодами происходит? В чем разница?

2 ответа

Решение

Помните, что запрос Linq - это просто запрос - он говорит: "если я запрашиваю эти данные, вот что я хочу_. Он не содержит никаких данных, но ожидает, пока вы не запросите_ результатов (через foreach, ToList, ToArray, так далее.)

Разница в том, что вы не захватываете список, возвращенный ToList в первом примере. Используется ForEach позвони но objects переменная по-прежнему содержит ссылку на исходный запрос. Когда вы просите об этом снова - он снова получает данные. Когда он снова получает данные, создаются новые объекты.

Так что в этом отношении - да ToList() создает новый список. Он не изменяет вызываемый объект, чтобы превратить его в список.

Во втором примере objects переменная содержит ссылку на список, сгенерированный из запроса через ToList(), поэтому, когда вы изменяете их и возвращаете objects вы возвращаете тот же список.

В вашем первом примере кода objects.ToList() на самом деле создает новый объект типа List ты работаешь со своим ForEach, После ForEach сделано, вы все еще только возвращаете IEnumerable и список, который вы на самом деле хотели вернуть, исчезнет.

Назначая запрос LINQ с помощью ToList() к object переменная, вы используете недавно созданный список в вашем ForEach,

Другие вопросы по тегам