Так что мой профессор отзывался о проекте, над которым я работал. Он установил несколько отметок для этого кода:
if (comboVendor.SelectedIndex == 0) {
createVendor cv = new createVendor();
cv.ShowDialog();
loadVendors();
}
Это в выпадающем списке «обработчик изменения индекса». Он используется, когда пользователь хочет создать нового поставщика, моя опция top (индекс 0, который никогда не меняется) открывает диалоговое окно «Создать нового поставщика». Таким образом, содержимое моего поля со списком выглядит так:
Create New Vendor...
Existing Vendor
Existing Vendor 2
Existing Vendor 3
Его проблема с кодом первой строки:
if (comboVendor.SelectedIndex == 0)
Он утверждает, что 0 должен быть константой, и на самом деле подсчитывал мне оценки из-за этого. Он утверждает, что я не должен использовать литералы в моем коде вообще.
Дело в том, что я не понимаю, почему я хотел бы сделать этот код в такой ситуации постоянным. Этот индекс никогда не изменится, и это не то, что вам нужно настроить. Кажется пустой тратой памяти хранить один 0 в памяти, который используется для очень специфической ситуации и никогда не меняется.
-1
instr.indexOf(substr) != -1
для «str
содержитsubstr
», полностью оправдано. Но здесь значение 0 не является ни очевидным (каково отношение к созданию нового поставщика?), Ни истинно постоянным (что, если способ создания нового поставщика изменяется?).int.Zero
вместо этого, чтобы сделать его счастливым :)Ответы:
Фактически правильный способ сделать это в C # - вообще не полагаться на порядок ComboItems .
источник
Порядок в поле со списком может измениться. Что, если вы добавите еще один параметр, например «Создать специального поставщика ...», перед вашим «Создать нового продавца ...»
Преимущество использования константы состоит в том, что если существует много методов, которые зависят от порядка поля со списком, вам нужно изменить только константу, а не все методы, если это действительно изменится.
Использование константы также более читабельно, чем литерал.
Большинство скомпилированных языков подставляют константу во время компиляции, поэтому нет снижения производительности.
источник
Эта ситуация, которую вы описываете, является оценочным, лично я бы не использовал ее, если бы она использовалась только один раз и была уже читабельной.
Реальный ответ - то, что он выбрал это, чтобы преподать вам урок.
Не забывайте, что он профессор, его задача - научить вас программированию и лучшим практикам.
Я бы сказал, что он неплохо справляется.
Конечно, он может показаться немного абсолютным, но я уверен, что вы подумаете еще раз, прежде чем использовать магические числа.
Кроме того, он попал под вашу шкуру, чтобы вы могли присоединиться к онлайн-сообществу программистов, чтобы узнать, что считается наилучшей практикой в этой ситуации.
Снимаю шляпу перед вашим профессором.
источник
Тот факт, что вам пришлось объяснить, доказывает, почему вы должны использовать константу. Если вы введете константу как
NEW_VENDOR_DIALOG
, ваш код будет более понятным. Кроме того, компиляторы оптимизируют константы, поэтому производительность не изменится.Пишите программы для программистов, а не для компиляторов. Если вы специально не пытаетесь микрооптимизировать, что не похоже на вас.
источник
Я бы согласился Использование нуля здесь "магия". Представьте, что вы читаете этот код впервые. Вы не знаете, почему ноль особенный, а литерал ничего не говорит вам о том, почему ноль особенный. Если вместо этого вы сказали,
if(comboVendor.SelectedIndex == CreateNewVendorIndex)
то начинающему читателю становится совершенно ясно, что означает код.Это крайняя позиция; реалистичной позицией было бы сказать, что использование литералов - это красный флаг, который указывает, что код может быть не таким ясным, как мог бы быть. Иногда это уместно.
То, что это никогда не изменится, является отличной причиной, чтобы сделать его постоянным . Вот почему константы называются константами; потому что они никогда не меняются.
В самом деле? Вы не можете увидеть любую ситуацию , в которой кто - то может потребоваться изменить порядок вещей в поле со списком?
Тот факт, что вы можете увидеть причину, по которой это может измениться в будущем, является хорошей причиной, чтобы не делать ее постоянной. Скорее это должно быть непостоянное целочисленное поле только для чтения. Константа должна быть величиной, которая гарантированно останется неизменной на все времена . Пи и атомный номер золота являются хорошими константами. Номера версий не являются; они меняют каждую версию. Цена на золото, очевидно, ужасная константа; это меняется каждую секунду. Делайте только постоянные вещи, которые никогда не изменятся .
Теперь мы подошли к сути вопроса.
Это, пожалуй, самая важная строка в вашем вопросе, поскольку она указывает на то, что у вас есть какое-то глубоко ошибочное понимание (1) памяти и (2) оптимизации. Вы в школе, чтобы учиться, и сейчас самое время получить правильное понимание основ. Можете ли вы объяснить подробно, почему вы считаете, что «держать в памяти один ноль»? Прежде всего, почему вы считаете, что оптимизация использования четырех байтов памяти в процессе с как минимум двумя миллиардами байтов адресуемой пользователем памяти имеет значение? Во-вторых, какой именно ресурс вы потребляете здесь ? Что вы подразумеваете под "памятью"?
Меня интересуют ответы на эти вопросы, во-первых, потому что они дают вам возможность узнать, насколько неверно ваше понимание оптимизации и управления памятью, и, во-вторых, потому что я всегда хочу знать, почему новички верят в причудливые вещи, чтобы я мог спроектировать лучшие инструменты, чтобы привести их к правильным убеждениям.
источник
Он прав. Вы правы. Ты не прав.
Концептуально он прав, что магических чисел следует избегать. Константы делают код более читабельным, добавляя контекст к тому, что означает число. В будущем, когда кто-то читает ваш код, он знает, почему использовался тот или иной номер. И если вам нужно изменить значение где-то вниз по линии, гораздо лучше изменить его в одном месте, а не пытаться выследить везде, где используется конкретное число.
Как говорится, вы правы. В этом конкретном случае я действительно не думаю, что константа оправдана. Вы ищете первый элемент в списке, который всегда равен нулю. Это никогда не будет 23. Или -pi. Вы специально ищете ноль. Я действительно не думаю, что вам нужно загромождать код, делая его константой.
Однако вы ошибаетесь, предполагая, что константа переносится как переменная, «используя память». Постоянная существует для человека и компилятора. Он говорит компилятору поместить это значение в это место во время компиляции, где вы в противном случае поместили бы буквальное число. И даже если бы он содержал постоянную в памяти для всех приложений, кроме самых требовательных, потеря эффективности даже не поддалась измерению. Беспокойство об использовании в памяти одного целого числа определенно попадает в «преждевременную оптимизацию».
источник
Я бы заменил на
0
константу, чтобы прояснить смысл, напримерNewVendorIndex
. Вы никогда не знаете, изменится ли ваш заказ.источник
Это полное предпочтение вашего профессора. Как правило, вы используете константу только в том случае, если литерал будет использоваться несколько раз, вы хотите, чтобы читатель понял, какова цель строки, или ваш литерал может быть изменен в будущем, и вы хотите изменить только это в одном месте. Тем не менее, в этом семестре профессор является начальником, так что я бы сделал это с этого момента в этом классе.
Хорошее обучение для корпоративного мира? Вполне возможно.
источник
Честно говоря, хотя я не думаю, что ваш код - лучшая практика, его предложение немного откровенно гротескно.
Более распространенной практикой для комбинированного списка .NET является присвоение элементу «Выбрать ..» пустого значения, в то время как фактические элементы имеют значимые значения, а затем выполните:
скорее, чем
источник
Он не ошибается, подчеркивая ценность использования констант, и вы не ошибаетесь, используя литералы. Если он не подчеркнул, что это ожидаемый стиль кодирования, вы не должны терять оценки за использование литералов, поскольку они не являются вредными. Я видел, как литералы повсеместно использовались в коммерческом коде.
Хотя его точка зрения хороша. Это может быть его способ познакомить вас с преимуществами констант:
1-Они защищают ваш код в некоторой степени от случайного вмешательства
2-Как @DeadMG говорит в своем ответе, что если во многих местах используется одно и то же литеральное значение, оно может ошибочно появиться с другим значением - поэтому константы сохраняют согласованность.
3-константы сохраняют тип, поэтому вам не нужно использовать что-то вроде 0F для обозначения нуля.
4-Для удобства чтения COBOL использует ZERO в качестве зарезервированного слова для нулевого значения (но также позволяет использовать буквальный ноль) - поэтому иногда полезно давать значение имени, например: (Источник: ms-Constants
или как в вашем случае (как показано в ответе @Michael Krussel)
источник
int weeks = 52
, нет 52 недель в году. В году 52,142857142857146 недель, и это число, на котором вы должны хранить дроби. Конечно, единственное, что на самом деле является постоянным во всем этом наборе констант количество месяцев.Вам нужно будет только ввести его в константу, если он имеет сложное происхождение или если он повторяется часто. Иначе буквальное в порядке. Поместить все в константу - это полное излишество.
источник
На самом деле, как уже упоминалось, что если его позиция изменится? Что вы могли бы / должны сделать, это использовать код, а не полагаться на индекс.
Итак, когда вы создаете свой список выбора, он заканчивается как HTML
Затем вместо того, чтобы проверять
selectedIndex === 0
, убедитесь, что это значениеCREATECODE
будет константным и использовалось бы как для этого теста, так и при создании списка выбора.источник
Я бы полностью избавился от этого. Просто поместите кнопку создания нового рядом со списком со списком. Дважды щелкните элемент в списке для редактирования или нажмите кнопку. Не используйте новую функциональность в поле со списком. Тогда магическое число удаляется совсем.
В общем, любое буквенное число в коде должно быть определено как константа, чтобы поместить контекст вокруг числа. Что значит ноль? В этом случае 0 = NEW_VENDOR. В других случаях это может означать что-то иное, поэтому для удобочитаемости и удобства сопровождения всегда полезно обрисовать контекст.
источник
Как уже говорили другие, вы должны использовать какой-то метод, отличный от номера индекса, чтобы идентифицировать элемент комбинированного списка, который соответствует данному действию; или вы можете найти индекс с некоторой программной логикой и сохранить его в переменной.
Причина, по которой я пишу, - обратиться к вашему комментарию по поводу «использования памяти». В C #, как и в большинстве языков, константы «сворачиваются» компилятором. Например, скомпилируйте следующую программу и проверьте IL. Вы обнаружите, что все эти цифры даже не попадают в IL, не говоря уже о памяти компьютера:
результирующий IL:
Таким образом, независимо от того, используете ли вы константу, литерал или килобайт кода с использованием константы, значение обрабатывается буквально в IL.
Связанный пункт: постоянное сворачивание применяется к строковым литералам. Многие считают, что такой вызов вызывает слишком много ненужной неэффективной конкатенации строк:
Но проверьте IL:
Итог: операторы в константных выражениях приводят к константным выражениям, а компилятор выполняет все вычисления; это не влияет на производительность во время выполнения.
источник