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

Обновлено: 21.11.2024

Исключение – это ошибка, возникающая во время выполнения программы. Исключения известны непрограммистам как экземпляры, не соответствующие общему правилу. Название «исключение» в информатике тоже имеет такое значение: оно подразумевает, что проблема (исключение) возникает нечасто, т.е. исключение есть «исключение из правила». Обработка исключений — это конструкция в некоторых языках программирования для автоматической обработки ошибок. Многие языки программирования, такие как C++, Objective-C, PHP, Java, Ruby, Python и многие другие, имеют встроенную поддержку обработки исключений.

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

Живое обучение Python

Нравится эта страница? Мы предлагаем живые обучающие курсы Python, охватывающие содержание этого сайта.

Обработка исключений в Python

Обработка исключений в Python очень похожа на Java. Код, который таит в себе риск исключения, встроен в блок try. В то время как в Java исключения перехватываются предложениями catch, в Python у нас есть операторы, представленные ключевым словом «кроме». Можно создавать «нестандартные» исключения: с помощью оператора повышения можно принудительно вызвать указанное исключение.

Давайте рассмотрим простой пример. Предположим, мы хотим попросить пользователя ввести целое число. Если мы используем input(), ввод будет строкой, которую мы должны преобразовать в целое число. Если ввод не является допустимым целым числом, мы сгенерируем (поднимем) ValueError. Мы покажем это в следующем интерактивном сеансе:

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

Это цикл, который прерывается, только если задано допустимое целое число. Вводится цикл while. Код в предложении try будет выполняться оператор за оператором. Если во время выполнения не возникает никаких исключений, выполнение дойдет до оператора break, и цикл while будет оставлен. Если возникает исключение, то есть при приведении n, оставшаяся часть блока try будет пропущена и будет выполнено предложение exclude. Вызванная ошибка, в нашем случае ValueError, должна соответствовать одному из имен после исключения. В нашем примере только один, т.е. "ValueError:". После вывода текста оператора печати выполняется еще один цикл. Он начинается с нового input().

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

Мы используем это в примере с собачьим возрастом из главы «Условные операторы».

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

Программное обеспечение — это набор инструкций или программ, которые сообщают компьютеру, что делать. Он не зависит от аппаратного обеспечения и делает компьютеры программируемыми. Существует три основных типа:

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

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

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

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

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

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

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

Важным отличием разработки программного обеспечения на заказ от разработки коммерческого программного обеспечения является разработка программного обеспечения на заказ. Разработка программного обеспечения на заказ — это процесс проектирования, создания, развертывания и обслуживания программного обеспечения для определенного набора пользователей, функций или организаций. Напротив, готовое коммерческое программное обеспечение (COTS) разработано с учетом широкого набора требований, что позволяет его упаковывать, продавать и распространять на коммерческой основе.

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

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

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

Проясните проблему, задав себе правильные вопросы

Это помогает прояснить проблему, с которой вы столкнулись, прежде чем пытаться ее исправить. Мы ожидаем, что вы уже столкнулись с проблемой в своем коде, иначе вы бы не пытались выяснить, как ее отладить! Итак, прежде чем приступать к отладке, убедитесь, что вы определили проблему, которую пытаетесь решить:

Что вы ожидали от своего кода?

Что произошло вместо этого?

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

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

Проверьте свои предположения

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

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

Правильно ли вы используете API? Возможно, вы использовали правильный API, но использовали его неправильно.

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

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

Вы ожидали, что объект или переменная будет содержать определенное значение (или определенный тип значения), которое отличается от того, что произошло на самом деле?

Знаете ли вы назначение кода? Часто сложнее отлаживать чужой код. Если это не ваш код, возможно, вам придется потратить время на изучение того, что именно делает код, прежде чем вы сможете эффективно его отлаживать.

При написании кода начинайте с малого и начинайте с работающего кода! (Здесь полезен хороший пример кода.) Иногда легче исправить большой или сложный набор кода, начав с небольшого фрагмента кода, демонстрирующего основную задачу, которую вы пытаетесь решить. Затем вы можете постепенно изменять или добавлять код, проверяя каждую точку на наличие ошибок.

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

Пройдитесь по коду в режиме отладки, чтобы найти источник проблемы

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

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

В Visual Studio вы входите в режим отладки, нажимая клавишу F5 (или команду меню "Отладка" > "Начать отладку" или кнопку "Начать отладку" на панели инструментов "Отладка"). Если возникают какие-либо исключения, помощник по исключениям Visual Studio перенесет вас точно в точку, где произошло исключение, и предоставит другую полезную информацию. Дополнительные сведения о том, как обрабатывать исключения в коде, см. в разделе Методы и инструменты отладки.

Если вы не получили исключение, возможно, вы знаете, где искать проблему в коде. Здесь вы используете точки останова с отладчиком, чтобы дать себе возможность более тщательно изучить свой код. Точки останова — это самая основная и важная функция надежной отладки. Точка останова указывает, где Visual Studio должна приостановить выполнение кода, чтобы вы могли просмотреть значения переменных, поведение памяти или последовательность выполнения кода.

В Visual Studio можно быстро установить точку останова, щелкнув в левом поле рядом со строкой кода. Или поместите курсор на строку и нажмите F9.

Создать образец приложения (с некоторыми ошибками)

Далее мы создадим приложение, в котором есть несколько ошибок.

Если вы еще не установили Visual Studio, перейдите на страницу загрузок Visual Studio, чтобы установить ее бесплатно.

Откройте Visual Studio.

Visual Studio создает консольный проект, который отображается в обозревателе решений на правой панели.

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

Запустите приложение

Нажмите F5 или кнопку "Начать отладку" на панели инструментов отладки, расположенной над редактором кода.

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

Но вместо этого мы видим следующее:

Глядя на вывод и на наш код, мы знаем, что GType — это имя класса, в котором хранится тип галактики. Мы пытаемся показать фактический тип галактики (например, "Спираль"), а не название класса!

Отладка приложения

При запущенном приложении установите точку останова, щелкнув в левом поле рядом с вызовом метода Console.WriteLine в этой строке кода.

Когда вы устанавливаете точку останова, на левом поле появляется красная точка.

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

Нажмите кнопку «Перезагрузить» на панели инструментов отладки (Ctrl + Shift + F5).

Приложение приостанавливается в установленной вами точке останова. Желтое выделение указывает, где отладчик приостановлен (желтая строка кода еще не выполнена).

Наведите указатель мыши на переменную GalaxyType справа, а затем слева от значка гаечного ключа разверните Galaxy.GalaxyType . Вы видите, что GalaxyType содержит свойство MyGType , а значение свойства равно Spiral .

"Спираль" на самом деле правильное значение, которое вы ожидали вывести на консоль! Так что это хорошее начало, когда вы можете получить доступ к этому значению в этом коде во время работы приложения. В этом случае мы используем неверный API. Посмотрим, сможем ли мы исправить это во время выполнения кода в отладчике.

В том же коде во время отладки поместите курсор в конец Galaxy.GalaxyType и измените его на Galaxy.GalaxyType.MyGType . Хотя вы можете внести это изменение, редактор кода показывает ошибку, указывающую на то, что он не может скомпилировать этот код. (В Visual Basic вы не увидите ошибку, и этот участок кода работает)

Для отладки примера кода Visual Basic пропустите следующие несколько шагов, пока не появится указание нажать кнопку "Перезапустить".

Нажмите «Изменить» в окне сообщения «Изменить и продолжить». Теперь вы видите сообщение об ошибке в окне списка ошибок. Ошибка указывает на то, что «объект» не содержит определения для MyGType .

Несмотря на то, что мы установили для каждой галактики объект типа GType (который имеет свойство MyGType), отладчик не распознает объект theGalaxy как объект типа GType . В чем дело? Вы хотите просмотреть любой код, который устанавливает тип галактики. Когда вы это сделаете, вы увидите, что класс GType определенно имеет свойство MyGType, но что-то не так. Подсказкой оказывается сообщение об ошибке об объекте; интерпретатору языка тип кажется объектом типа object вместо объекта типа GType .

Просматривая свой код, связанный с установкой типа галактики, вы обнаруживаете, что свойство GalaxyType класса Galaxy указано как object вместо GType .

Замените предыдущий код на этот:

Нажмите кнопку "Перезапустить" на панели инструментов отладки (Ctrl + Shift + F5), чтобы перекомпилировать код и перезапустить его.

Теперь, когда отладчик останавливается на Console.WriteLine , вы можете навести указатель мыши на Galaxy.GalaxyType.MyGType и убедиться, что значение задано правильно.

Удалите точку останова, щелкнув кружок точки останова на левом поле (или щелкните правой кнопкой мыши и выберите "Точка останова" > "Удалить точку останова"), а затем нажмите F5, чтобы продолжить.

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

Установите точку останова в этой строке кода перед оператором switch (перед оператором Select в Visual Basic).

В этом коде задается тип галактики, поэтому мы хотим рассмотреть его поближе.

Нажмите кнопку "Перезапустить" на панели инструментов отладки (Ctrl + Shift + F5), чтобы перезапустить программу.

Отладчик останавливается на строке кода, где вы установили точку останова.

Наведите указатель мыши на переменную типа. Вы видите значение S (после кода символа). Вас интересует значение I , так как вы знаете, что это неправильный тип галактики.

Нажмите F5 и снова наведите указатель мыши на переменную типа. Повторяйте этот шаг, пока не увидите значение I в переменной типа.

Теперь нажмите F11 ("Отладка" > "Пошаговый переход" или кнопка "Пошаговый переход" на панели инструментов отладки).

F11 запускает отладчик (и выполняет код) по одному оператору за раз. F10 (Шаг с обходом) — похожая команда, и обе они чрезвычайно полезны при обучении работе с отладчиком.

Нажимайте клавишу F11, пока не остановитесь на строке кода в операторе switch для значения "I" (оператор Select для Visual Basic). Здесь вы видите явную проблему, возникшую из-за опечатки. Вы ожидали, что код переместится туда, где он устанавливает MyGType как неправильный тип галактики, но вместо этого отладчик полностью пропускает этот код и делает паузу в разделе по умолчанию оператора switch (оператор Else в Visual Basic).

Глядя на код, вы видите опечатку в операторе case 'l'. Это должен быть регистр 'I' .

Нажмите на код случая "l" и замените его на случай "I".

Удалите точку останова, а затем нажмите кнопку "Перезапустить", чтобы перезапустить приложение.

Ошибки исправлены, и вы видите ожидаемый результат!

Нажмите любую клавишу, чтобы закрыть приложение.

Обзор

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

Если трудно определить область кода, в которой возникает проблема, установите точку останова в коде, который выполняется до возникновения проблемы, а затем используйте пошаговые команды, пока не увидите манифест проблемы. Вы также можете использовать точки трассировки для записи сообщений в окно вывода. Просматривая зарегистрированные сообщения (и замечая, какие сообщения еще не были зарегистрированы!), вы часто можете изолировать область кода с проблемой. Возможно, вам придется повторить этот процесс несколько раз, чтобы сузить его.

Когда вы найдете область кода с проблемой, используйте отладчик для исследования. Чтобы найти причину проблемы, проверьте код проблемы во время запуска приложения в отладчике:

Проверить переменные и проверить, содержат ли они тип значений, которые они должны содержать. Если вы обнаружите неверное значение, узнайте, где оно было установлено (чтобы найти место, где было установлено значение, вам может потребоваться либо перезапустить отладчик, либо просмотреть стек вызовов, либо и то, и другое).

Проверьте, выполняет ли ваше приложение ожидаемый код. (Например, в примере приложения мы ожидали, что код оператора switch задаст для типа галактики значение Irregular, но приложение пропустило этот код из-за опечатки.)

Вы используете отладчик, чтобы помочь вам найти ошибки. Инструмент отладки может найти ошибки за вас, только если ему известно назначение вашего кода. Инструмент может знать назначение вашего кода только в том случае, если вы, разработчик, выражаете это намерение. Написание модульных тестов — это то, как вы это делаете.

Дальнейшие шаги

Из этой статьи вы узнали несколько общих концепций отладки. Далее вы можете начать узнавать больше об отладчике.

О до-диезе

Об этом учебнике по программированию на C Sharp

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

Как видите, объекты Point и Pen были созданы одинаково, но значение point1 осталось неизменным, когда новое значение координаты X было присвоено point2 , тогда как значение Pen1 было изменено, когда для pen2 был назначен новый цвет. Таким образом, мы можем вывести, что точки point1 и point2 содержат собственную копию объекта Point, тогда как pen1 и pen2 содержат ссылки на один и тот же объект Pen. Но как мы можем узнать это, не проведя этот эксперимент?

Ответ заключается в том, чтобы просмотреть определения типов объектов (что можно легко сделать в Visual Studio, поместив курсор на имя типа объекта и нажав F12):

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

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

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

Первая сигнатура метода (т. е. без параметра compareType) фактически аналогична использованию оператора ==, но имеет то преимущество, что она явно применяется к строкам. Он выполняет порядковое сравнение строк, которое в основном представляет собой побайтовое сравнение. Во многих случаях это именно тот тип сравнения, который вам нужен, особенно при сравнении строк, значения которых задаются программно, например имена файлов, переменные среды, атрибуты и т. д.В этих случаях, если порядковое сравнение действительно является правильным типом сравнения для этой ситуации, единственным недостатком использования метода Equals без сравненияType является то, что кто-то, читающий код, может не знать, какой тип сравнения вы делаете.

Однако использование сигнатуры метода Equals, которая включает в себя compareType при каждом сравнении строк, не только сделает ваш код более понятным, но и заставит вас явно задуматься о том, какой тип сравнения вам нужно выполнить. Это стоит сделать, потому что даже если английский язык не может обеспечить много различий между порядковыми и учитывающими культуру сравнениями, другие языки предоставляют множество, и игнорирование возможностей других языков открывает перед вами большой потенциал для ошибки в пути. Например:

Самая безопасная практика — всегда указывать параметр compareType в методе Equals. Вот несколько основных рекомендаций:

  • При сравнении строк, которые были введены пользователем или должны отображаться пользователю, используйте сравнение с учетом языка и региональных параметров ( CurrentCulture или CurrentCultureIgnoreCase ).
  • При сравнении программных строк используйте порядковое сравнение ( Ordinal или OrdinalIgnoreCase ).
  • InvariantCulture и InvariantCultureIgnoreCase обычно не следует использовать, за исключением очень ограниченного числа случаев, поскольку порядковые сравнения более эффективны. Если необходимо сравнение с учетом культуры, его обычно следует выполнять с текущей культурой или другой конкретной культурой.

можно просто написать:

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

Например, рассмотрим следующее утверждение:

Что произойдет, если один из объектов account.Status будет равен «Активный» (обратите внимание на заглавную букву А)? Ну, если бы myAccounts был объектом DbSet (который был настроен с конфигурацией по умолчанию без учета регистра), выражение where все равно соответствовало бы этому элементу. Однако если бы myAccounts находились в массиве в памяти, они бы не совпадали и, следовательно, давали бы другой общий результат.

Но подождите минутку. Когда мы говорили о сравнении строк ранее, мы видели, что оператор == выполняет порядковое сравнение строк. Так почему же в этом случае оператор == выполняет сравнение без учета регистра?

Как упоминалось ранее, операторы LINQ работают с любым объектом, который реализует IEnumerable. Например, следующая простая функция суммирует балансы на любом наборе счетов:

Ответ заключается в том, что Sum() не является методом, определенным в интерфейсе IEnumerable. Скорее, это статический метод (называемый «метод расширения»), определенный в классе System.Linq.Enumerable:

Так чем же метод расширения отличается от любого другого статического метода и что позволяет нам получить к нему доступ в других классах?

Отличительной характеристикой метода расширения является модификатор this в его первом параметре. Это «волшебство», которое идентифицирует его для компилятора как метод расширения. Тип параметра, который он изменяет (в данном случае IEnumerable ), обозначает класс или интерфейс, который затем появится для реализации этого метода.

(Кроме того, нет ничего волшебного в сходстве между именем интерфейса IEnumerable и именем класса Enumerable, для которого определен метод расширения. Это сходство — просто произвольный стилистический выбор.)

При таком понимании мы также можем видеть, что функцию sumAccounts, которую мы представили выше, можно было бы вместо этого реализовать следующим образом:

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

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

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

Если существует тип коллекции, специально предназначенный для типа имеющегося у вас элемента (например, строка или бит), склоняйтесь к использованию его в первую очередь. Реализация, как правило, более эффективна, когда она нацелена на определенный тип элемента.

В среде CLR используется сборщик мусора, поэтому вам не нужно явно освобождать память, созданную для какого-либо объекта. На самом деле, вы не можете. В C нет эквивалента оператору удаления C++ или функции free(). Но это не значит, что вы можете просто забыть обо всех объектах после того, как закончили их использовать. Многие типы объектов инкапсулируют некоторые другие типы системных ресурсов (например, файл на диске, соединение с базой данных, сетевой сокет и т. д.). Если оставить эти ресурсы открытыми, общее количество системных ресурсов может быстро истощиться, что приведет к снижению производительности и, в конечном итоге, к сбоям программы.

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

Создавая блок using в приведенном выше примере, вы точно знаете, что myFile.Dispose() будет вызываться, как только вы закончите работу с файлом, независимо от того, генерирует ли Read() исключение.

Самой очевидной ошибкой, которая может возникнуть при использовании метода 2, будет невозможность проверить возвращаемое значение. Это, вероятно, приведет к возможному исключению NullReferenceException, которое может появиться гораздо позже, что значительно усложнит отслеживание источника проблемы. В отличие от этого, метод 1 немедленно вызвал бы исключение InvalidCastException, что сделало бы источник проблемы более очевидным.

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

Вот несколько примеров других распространенных пар методов, где один генерирует исключение, а другой нет:

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

Однако неверно предполагать, что TryParse обязательно является «лучшим» методом. Иногда это так, иногда нет. Вот почему есть два способа сделать это. Используйте правильный вариант для контекста, в котором вы находитесь, помня, что исключения, безусловно, могут быть вашими друзьями как разработчика.

Но если вы проигнорируете предупреждение такого типа, рано или поздно что-то вроде этого вполне может попасть в ваш код:

А с той скоростью, с которой Intellisense позволяет нам писать код, эта ошибка не так уж невероятна, как кажется.

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

Помните, что компилятор C Sharp предоставляет много полезной информации о надежности вашего кода… если вы слушаете. Не игнорируйте предупреждения. Обычно их исправление занимает всего несколько секунд, а исправление новых, когда они происходят, может сэкономить вам часы. Приучите себя ожидать, что в окне «Список ошибок» Visual Studio будет отображаться «0 ошибок, 0 предупреждений», чтобы любые предупреждения вызывали у вас достаточно дискомфорта, чтобы вы могли немедленно их устранить.

Подведение итогов

Дополнительная литература в блоге Toptal Engineering:

Понимание основ

Читайте также: