Инициализировать поля класса в конструкторе или при объявлении?

Расширение ответа @ Kiran, которое я согласен, более кратким и Pythonic, это добавляет кодеки для поддержки чтения и записи UTF-8:

import codecs 

from tempfile import mkstemp
from shutil import move
from os import remove


def replace(source_file_path, pattern, substring):
    fh, target_file_path = mkstemp()

    with codecs.open(target_file_path, 'w', 'utf-8') as target_file:
        with codecs.open(source_file_path, 'r', 'utf-8') as source_file:
            for line in source_file:
                target_file.write(line.replace(pattern, substring))
    remove(source_file_path)
    move(target_file_path, source_file_path)
382
задан Robert Columbia 18 September 2016 в 18:44
поделиться

7 ответов

Мои правила:

  1. не инициализируют со значениями по умолчанию в объявлении (null, false, 0, 0.0 †¦).
  2. Предпочитают инициализацию в объявлении, если у Вас нет параметра конструктора, который изменяет значение поля.
  3. , Если значение полевых изменений из-за параметра конструктора поместило инициализацию в конструкторов.
  4. Быть последовательным в Вашей практике (самое важное правило).
284
ответ дан poke 18 September 2016 в 18:44
поделиться

В C# это не имеет значения. Эти два примера кода, которые Вы даете, совершенно эквивалентны. В первом примере компилятор C# (или действительно ли это - CLR?) создаст пустого конструктора и инициализирует переменные, как будто они были в конструкторе (существует небольшой нюанс к этому, который Jon Skeet объясняет в комментариях ниже). Если уже будет конструктор тогда, то любая инициализация "выше" будет перемещена в вершину его.

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

145
ответ дан Quibblesome 18 September 2016 в 18:44
поделиться

Семантика C# отличается немного от Java здесь. В присвоении C# в объявлении выполняется прежде, чем назвать конструктора суперкласса. В Java это сразу сделано, после которого позволяет 'этому' использоваться (особенно полезный для анонимных внутренних классов) и означает, что семантика двух форм действительно соответствует.

, Если Вы можете, сделайте полевой финал.

15
ответ дан Tom Hawtin - tackline 18 September 2016 в 18:44
поделиться

Принятие типа в Вашем примере, определенно предпочтите инициализировать поля в конструкторе. Исключительные случаи:

  • Поля в статических классах/методах
  • Поля, введенные как статичный/заключительный/и др.

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

6
ответ дан Noel 18 September 2016 в 18:44
поделиться

Что, если я сказал Вам, это зависит?

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

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

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

И в C++ я часто не делаю рядом ни с какой инициализацией ни в одном месте и перемещаю его в Init () функция. Почему? Ну, в C++, если Вы инициализируете что-то, что может выдать исключение во время объектной конструкции, которую Вы открываете сами для утечек памяти.

4
ответ дан almic 18 September 2016 в 18:44
поделиться

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

, Если значение Вы собираетесь присвоить переменной экземпляра, не добирается под влиянием ни одного из параметров, которые Вы собираетесь передать Вам, конструктор тогда присваивает его во время объявления.

0
ответ дан Iker Jimenez 18 September 2016 в 18:44
поделиться

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

1
ответ дан John Meagher 18 September 2016 в 18:44
поделиться