Страницы

Поиск по вопросам

пятница, 29 марта 2019 г.

Foreach и новый объект

Вот к примеру такой код, он загружает картинки из файлов и считает максимальную ширину и суммарную высоту:
List bitmapsList = new List(); foreach (string fn in fileNames) { Bitmap bmp = new Bitmap(fn); // Интересует вот эта строка bitmapsList.Add(bmp); if (bmp.Width > maxWidth) maxWidth = bmp.Width; totalHeight += bmp.Height; }
Вопрос: как будет правильней, создавать объект Bitmap bmp в цикле, или объявить его перед циклом? Что происходит с ним после прохода одной интерации цикла?


Ответ

Упрощенно можно считать что переменные, объявленные внутри блока ограниченного { } существуют до тех пор, пока выполняется код этого блока. Как только управление передается за пределы блока, все локальные переменные блока удаляются.
С объектами иначе. Объект существует до тех пор, пока к нему можно получить доступ по ссылке. Когда ни одной живой ссылки не осталось, объект может быть удален сборщиком мусора.
В реальности механизм в обоих случаях сложнее, но для начального понимания этого достаточно.
В вашем коде, переменные объявленные внутри цикла будут пересоздаваться на каждой итерации. Ссылку на Bitmap вы кладете в List объявленный за пределами цикла, поэтому с ним ни чего не произойдет.
Создание объекта, происходит в момент вызова конструктора new Bitmap(fn), и оно разумеется должно быть внутри цикла.
Что касается вопроса "как лучше?" - чем код понятнее, тем лучше, компилятор и Jit-компилятор в процессе работы все равно оптимизируют и изменят его так, как посчитают нужным и эффективным. Хотя надо отметить, что для языков на основе стековой машины, C# в их числе, присутствует рекомендация - объявлять переменную максимально близко к месту ее использования, т.е. если переменная используется только внутри итерации цикла и ее значение не участвует в последующих итерациях - объявляем ее внутри цикла, в противном случае вне цикла.
Ну и потратьте день другой, на целенаправленное изучение/повторение основ языка, принципов работы с памятью и сборки мусора в .NET, это реально нужно, если конечно вы планируете развиваться дальше в этом направлении. Вот тут есть отличный список литературы.

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

Отправить комментарий