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

Должен ли я всегда/никогда/никогда не инициализировать поля объектов значениями по умолчанию?

Вопрос о стиле кода здесь.

Я посмотрел на этот вопрос, который спрашивает, действительно ли .NET CLR всегда будет инициализировать значения полей. (Ответ - да.) Но мне кажется, что я не уверен, что это всегда хорошая идея, чтобы он это делал. Мое мышление состоит в том, что если я увижу объявление вроде этого:

int myBlorgleCount = 0;

У меня довольно хорошая идея, что программист ожидает, что счет начнется с нуля, и это нормально, по крайней мере, для ближайшего будущего. С другой стороны, если я просто вижу:

int myBlorgleCount;

У меня нет реальной непосредственной идеи, если 0 - юридическое или разумное значение. И если программист только начинает читать и модифицирует его, я не знаю, должен ли программист начать использовать его, прежде чем они установили для него значение, или если они ожидали, что он будет равен нулю и т.д.

С другой стороны, некоторые довольно умные люди и утилита очистки кода Visual Studio говорят мне удалить эти избыточные объявления. Каков общий консенсус по этому поводу? (Есть ли консенсус?)

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

EDIT. Хотя я и сказал, что этот вопрос является агностиком языка, он явно не применим к таким языкам, как C, где инициализация значения не выполняется.

РЕДАКТИРОВАТЬ: я ценю ответ Джона, но это именно то, что я не ищет. Я понимаю, что .NET(или Java или что-то еще) выполнит задание и инициализирует значения последовательно и правильно. Я хочу сказать, что если я вижу код, который модифицирует значение, которое ранее не было явно задано в коде, я, как разработчик кода, не знаю, означал ли исходный кодер его значение по умолчанию, или просто забыл установить значение или ожидал, что он будет установлен в другом месте и т.д.

4b9b3361

Ответ 1

Подумайте о долгосрочном обслуживании.

  • Сохраняйте код как можно более ясным.
  • Не полагайтесь на специфические для языка способы инициализации, если вам это не нужно. Может быть, более новая версия языка будет работать по-другому?
  • Будущие программисты поблагодарят вас.
  • Руководство будет благодарить вас.
  • Почему обманывают вещи даже малейшие?

Обновление: Будущие сопровождающие могут происходить из другого фона. Речь идет не о том, что "правильно", а в том, что будет проще всего в конечном итоге.

Ответ 2

Вы всегда в безопасности, полагая, что платформа работает так, как работает платформа. Платформа .NET инициализирует все поля значениями по умолчанию. Если вы видите поле, которое не инициализируется кодом, это означает, что поле инициализируется CLR, а не то, что оно не инициализировано.

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


Другим ненужным похмелье из прошлого является следующее:

string foo = null;
foo = MethodCall();

Я видел это от людей, которые должны знать лучше.

Ответ 3

Я думаю, что имеет смысл инициализировать значения, если он разъясняет намерение разработчика.

В С# нет никаких накладных расходов, так как все значения все инициализируются. В C/С++ неинициализированные значения будут содержать значения мусора/неизвестные (все, что было в ячейке памяти), поэтому инициализация была более важной.

Ответ 4

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

Но я думаю, что это общая проблема со всеми языковыми функциями. Мое мнение о том, что это: Если это официальная функция языка, вы можете использовать его. (Конечно, есть некоторые анти-функции, которые следует использовать с осторожностью или избегать вообще, например отсутствует option explicit в Visual Basic или наследование алмазов на С++)

Было время, когда я был очень параноидальным и добавил все ненужные инициализации, явные приведения, über-параноидальные блоки try-finally,... Я даже подумал об игнорировании автоматического бокса и замене всех вхождений явным типом конверсии, просто "чтобы быть в безопасности".

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

Помните: это только волшебство, пока вы его не поймете.

Ответ 5

Я согласен с вами; он может быть многословным, но мне нравится:

int myBlorgleCount = 0;

Теперь я всегда начинаю строки:

string myString = string.Empty;

(Я просто ненавижу нулевые строки.)

Ответ 6

В случае, когда я не могу сразу установить его на что-то полезное

int myValue = SomeMethod();

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

int myValue;

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

int myValue = 0;

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

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

Ответ 7

По моему опыту я обнаружил, что явно инициализация локальных переменных (в .NET) добавляет больше беспорядка, чем ясности.

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

Ответ 8

Я всегда инициализирую поля явно в конструкторе. Для меня это место для этого.

Ответ 9

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

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

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

На данный момент я считаю, что это прекрасно, чтобы инициализировать значение; то, что когда-то было имплицитно, становится явным. В долгосрочной перспективе, скажем, в ближайшие 10-20 лет люди могут начать изучать, что значение по умолчанию возможно, ожидается и известно, особенно если они остаются согласованными между языками (например, пустая строка для строк, 0 для чисел).

Ответ 10

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

Ответ 11

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

Ответ 12

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

Ответ 13

Это помечено как языковое агностическое, но большинство ответов относится к С#.

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

Ответ 14

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

Ответ 15

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

public int Count { get; set; }

Ответ 17

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

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

Чтобы использовать грубую аналогию, рассмотрим следующие два условия:

  • `if (xposition!= 0)...
  • `if ((flags и WoozleModes.deluxe)!= 0)...

В первом сценарии сравнение с буквальным нулем имеет смысл, поскольку оно проверяет позицию, которая семантически не отличается от любой другой. Во втором случае, однако, я бы предположил, что сравнение с литеральным нулем ничего не добавляет к удобочитаемости, поскольку код действительно не интересует, является ли значение выражения (flags & WoozleModes.deluxe) числом, отличным от нуля, а скорее он "не пуст".

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