Избегайте или обнимайте конструкции C #, которые разбивают редактирование и продолжаются?

StackOverflow https://stackoverflow.com/questions/3865454

Вопрос

Я разрабатываю и поддерживаю большие (500K + LOC) приложение WinForms, написанные в C # 2.0. Это многопользователь и в настоящее время развернут около 15 машин. Развитие системы продолжается (можно рассматривать как вечную бета), и очень мало сделано для защиты пользователей из потенциальных новых ошибок, которые могут быть введены в еженедельную сборку.

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

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

  • Анонимные методы и встроенные делегаты (если не полностью невозможно переписать)
  • Общие методы (кроме устойчивого, неизменного утилита)
  • Направленные на проекты на «любой ЦП» (то есть никогда не выполняются в 64-битных)
  • Инициализирующие поля в точке декларации (инициализация перемещается в конструктор)
  • Письменные блоки перечисления, которые используют yield (кроме в утилите)

Теперь я полностью осознаю, что новые языковые функции в C # 3 и 4 в основном несовместимы с редактированием и-продолжением (strambda выражениями, linq и т. Д.). Это одна из причин, по которым я сопротивлялся перемещению проекта до более новой версии рамки.

Мой вопрос заключается в том, является ли хорошая практика, чтобы избежать использования этих более продвинутых конструкций в пользу кода, который очень легко отладить? Есть ли легитимность в таком роде развитии, или это расточительно? Также, главное, делайте любую из этих конструкций (лямбда-выражения, анонимные методы и т. Д.) Возбуть производительность / накладные расходы на память, которые хорошо написаны, редактируемый-и--совместимый код может избежать? ... Или выполните внутреннюю работу компилятора C #, делают такие продвинутые конструкции, которые будут работать быстрее, чем вручную, написанный «расширенный» код?

Это было полезно?

Решение

Не желая надевать Trite - это хорошая практика для записи тестов / интеграции, а не полагаться на редактирование.

Таким образом, вы расходуете усилия один раз, и каждый другой раз «свободен» ...

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

Как @dave Swersky упоминает в комментариях, книга MCHAEL перьев, Эффективно работает с устаревшим кодом Это хороший ресурс (это наследие 5 минут после того, как вы написали, верно?)

Итак, да, я думаю, что это ошибка, чтобы избежать новых C # Brequouts в пользу разрешения для редактирования и продолжения; Но я также думаю, что это ошибка, чтобы принять новые конструкции только ради этого, и особенно если они приведут к сложнее понять код.

Другие советы

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

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

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

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

Ваш подход не должен быть черным и белым.

Хотел уточнить эти вещи немного

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

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

Все можно попробовать и проверить в режиме реального времени, не прекращая процесс.

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

В целом, хотя да, я думаю, что это ошибка, чтобы избежать новых C # AIROTS в пользу, что позволяет для редактирования и продолжения. Редактировать и продолжить - отличная функция (действительно любила его, когда я впервые столкнулся с ним в моих дней C ++). Но это значение в качестве помощника по производству сервера не состоит в том, чтобы получить рост произведений из новых функций C # IMHO.

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

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

  1. Менее выразительно
  2. Дольше
  3. Повторяется (от избежания общих методов)
  4. Не портативный (никогда не отладки и тестируйте 64 бит ??!?!?)

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

Я бы написал лучший код, а не код, который делает функцию вашей работы IDE.

Хотя нет ничего, по своей природе не так с вашим подходом, он ограничивает вам количество выраженности, понятого IDE. Ваш код становится отражением это Возможности, а не языки, и, таким образом, ваше общее значение в мире разработки уменьшается, потому что вы держите себя от изучения других методов повышения производительности производительности. Предотвращение LINQ в пользу редактирования и продолжения чувствует себя как огромная возможность для меня лично, но парадокс состоит в том, что вы должны набрать некоторый опыт, прежде чем вы сможете почувствовать этот путь.

Кроме того, как упоминалось в других ответах, тестирование единиц вашего кода удаляет нужно Для запуска всего приложения все время и, таким образом, решает вашу дилемму по-другому. Если вы не сможете щелкнуть правой кнопкой мыши в своем IDE и проверьте, только 3 строки кода, которые вы заботитесь о, вы уже слишком много работаете во время развития.

Вы должны действительно представить интеграцию продолжения, которые могут помочь вам найти и устранять ошибки перед развертыванием программного обеспечения. Особенно большие проекты (я считаю, что 500K довольно большой) нуждается в какой-то валидации.

http://www.codinghorror.com/blog/2006/02/revisiting-edit-and-continue.html.

Что касается конкретного вопроса: не избегайте этих конструкций и не полагайтесь на свои безумные навыки отладки - старайтесь вообще избегать ошибок (в развернутом программном обеспечении). Вместо этого пишите модули.

Я также работал на очень крупных проектах постоянного бета.

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

Я использовал общие методы и классы для повторного использования и надежности.

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

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

Все это полезно для поддержания большого быстро меняющегося проекта в надежном состоянии.

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

Есть много, я сделаю, чтобы облегчить находить ошибки, но не так ли облегчить ошибки.

Вы могли бы попробовать Тестовое развитие. Отказ Я нашел это очень полезным, чтобы вообще не использовали отладчик. Вы начинаете с нового теста (например, тест на единицу), а затем вы запускаете этот тест на единицу, чтобы проверить вашу разработку - вам не нужно все время приложения. И это означает, что вам не нужно редактировать и-продолжение!

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

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

Однако очень трудно судить, следует ли использовать язык или не следует использовать языковые функции или нет, потому что это также зависит от многих, многие другие факторы: Project Reqs, сроки выпуска, командные навыки, стоимость управляемости кода после рефакторинга, чтобы назвать несколько Отказ

Надеюсь это поможет!

Проблема, в которой вы, кажется, имеете:

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

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

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

Разделяя код UI в другие классы, которые могут быть проверены с модульными тестами, позволит вам использовать все конструкции C # в этих классах. Тогда вы можете просто ограничить конструкции в использовании в пользовательском интерфейсе.

Когда я начал писать много модульных тестов, мое использование «редактирования-и-продолжения» спустилось, я как вряд ли использовать его отдельно от кода UI.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top