Моя персональная инструкция: исключение выдается, когда фундаментальное предположение о текущем блоке кода, как находят, является ложью.
Пример 1: скажите, что у меня есть функция, которая, как предполагается, исследует произвольный класс и возвращает true, если тот класс наследовался List<>. Эта функция задает вопрос, "Это - объект потомок Списка?" Эта функция никогда не должна выдавать исключение, потому что нет никаких серых областей в его операции - каждый класс или делает или не наследовался List<>, таким образом, ответ всегда - "да" или "нет".
Пример 2: скажите, что у меня есть другая функция, которая исследует List<> и возвращает true, если его длина - больше чем 50 и ложь, если длина меньше. Эта функция задает вопрос, "Этот список имеет больше чем 50 объектов?" Но этот вопрос делает предположение - он предполагает, что объект, который он дан, является списком. Если я вручаю ему ПУСТОЙ УКАЗАТЕЛЬ, то то предположение является ложью. В этом случае, если функция возвращается или верный или ложь, то это нарушает свои собственные правила. Функция не может возвратиться ничто и утверждать, что ответила на вопрос правильно. Таким образом, это не возвращается - это выдает исключение.
Это сопоставимо с "загруженный вопрос" логическая ошибка. Каждая функция задает вопрос. Если вход, который это дано, делает тот вопрос ошибкой, то выдайте исключение. Эту линию более трудно провести с функциями, которые возвращаются пусто, но нижняя строка: если предположения функции о ее исходных данных нарушены, это должно выдать исключение вместо того, чтобы обычно возвратиться.
другая сторона этого уравнения: если Вы находите свои функции, выдающие исключения часто, то, вероятно, необходимо совершенствовать их предположения.
Деструктор будет вызываться, когда сборщик мусора решит, что он должен очистить некоторые старые объекты. Вы не можете полагаться на время выполнения деструкторов в .NET
. Вместо этого вы должны использовать Dispose (), если вы хотите очистить некоторые ресурсы, когда они не нужны (особенно когда у вас есть какие-либо неуправляемые ресурсы, такие как соединения TCP, соединения SQL. и т. д.)
Если критически важно, чтобы время жизни ваших объектов управлялось, наследуйте от IDisposible, и вы можете использовать using ключевое слово .
Деструкторы (или финализаторы - некоторые люди предпочитают их называть) вообще запускаются в отдельном потоке. Они запускаются в определенное время. Их работа не гарантируется до конца срока службы ваших приложений, и даже в этом случае возможно, что они не перезвонят.
Деструкторы или финализаторы, как они также называются, вызываются в определенный момент времени после того, как ваш экземпляр становится доступным для сборки мусора. Это не происходит в детерминированный момент времени, как в C ++.
Деструктор (финализатор) будет вызван, как только сборщик мусора определит, что ваш объект больше не используется. Финализаторы запускаются в потоке финализатора одновременно с вашей основной программой!
При правильной оптимизации (компилятор JIT может легко исключить локальную переменную), это может быть уже внутри ] первый вызов DoSomeFunThingsWithMyObject (если этот метод больше не нуждается в параметрах) или в любое более позднее время.