Подтвердить что ты не робот

Лучшая практика создания объектов, используемых для циклов for/foreach

Какая наилучшая практика для работы с объектами для циклов foreach или foreach? Должны ли мы создать один объект за пределами циклов и воссоздать его снова (используя новый...) или создать новый для каждой итерации цикла?
Пример:

foreach(var a in collection)
{
  SomeClass sc = new SomeClass();
  sc.id = a;
  sc.Insert();
}

или

SomeClass sc = null;
foreach(var a in collection)
{
  sc = new SomeClass();
  sc.id = a;
  sc.Insert();
}

Что лучше?

4b9b3361

Ответ 1

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

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

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

Ответ 2

Во-первых, я отмечаю, что вы имеете в виду "создание переменных", когда вы говорите "создание объектов". Ссылки на объекты идут в переменных, но они не являются самими переменными.

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

http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/

для деталей.

Ответ 3

Я уверен, что кто-то может вытолкнуть анализ MSIL, но практически нет заметной разницы в исполнении или производительности. Единственное, что вы затрагиваете, это хранение ссылки на объект.

Я говорю, держите его чистым и простым; объявить переменную внутри цикла. Это обеспечивает принцип открытого/закрытого на практике, поэтому вы знаете область применения переменной и не используются повторно в других местах. В следующем цикле переменная теряет область действия и автоматически инициализируется.

Ответ 4

Вы создаете новый объект в каждой итерации цикла в обоих случаях (так как вы вызываете new SomeClass()).

В предыдущем подходе ясно, что sc используется только внутри цикла, что может быть преимуществом с точки зрения обслуживания.

Ответ 5

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

Ответ 6

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

Ответ 7

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