От if == null вы уходите, только если ссылочный тип не может быть null
Совершенно верно. Заодно компилятор даст по рукам, тому кто попытается null туда запихнуть.
а если может — вы снова напишите шаблонную проверку.
Совершенно верно. Только после первой же успешной проверки у меня будет значение ссылочного типа, не допускающего null и его, в отличие от нынешних, не надо будет проверять по всей глубине стека вызовов. Заодно компилятор даст по рукам тому, кто рискнет пропустить обязательную проверку.
Итоги:
Полностью исключены проверки с выбросом InvalidArgumentException
А там где null — не ошибка, наличие проверки проконтролирует компилятор.
98 год?
Да, все то, про что я думал как о лучших альтернативах, еще не существовало, даже файберы надо руками писать.
Дикий капитализм — цена разработки системы меньше чем недельная прибыль от ее эксплуатации, офигеть.
У меня нет такой статистики, к сожалению — я уже давно не работаю в той компании. Да и 10 лет тому проекту нет и сейчас. Условия тоже иные — требования по надежности менее жесткие, а вот унаследованного технического долга был вагон и маленькая тележка. Тем не менее от исключений, которые сами по себе означали ошибку в коде, мы избавились.
Это маркетинговые сказки. Или некомпетентность. Невозможно отловить все ошибки
Речь ни в коем случае не идет об ликвидации всех ошибок! Я имею в виду только предотвращение тех из них, которые вызывают исключения, чей тип гарантированно означает ошибку в коде (не в окружении и не во входных данных).
Следующее по опасности — FPE.
Это исключение само по себе ошибку в коде не означает. Но в ваших условиях его цена понятна. Остальное из вашей четверки для меня всегда было уже некрологом.
Только забыли упомянуть, что он появился лишь в Delphi 5, и в VCL далеко не всегда используется.Так что получить NRE в деструкторе формы после исключения во время создания формы — не так сложно.
Коммерческий опыт у меня начался с Delphi 7. Для младших версий FreeAndNil несложно написать самому. От формы (а в идеале от GUI вообще) исправность системы ИМХО зависеть не должна.
PS: Большая статья о вашей системе станет украшением любого тематического сайта.
"Всего лишь механизм транзакций" — это уже из серии "90% любой крупной программы на C++ представляет собой медленную и глючную реализацию подмножества спецификации Common Lisp" (по памяти).
Если нужны качества, которые может дать только безопасный рантайм — логично использовать готовый и проверенный безопасный рантайм вместо велосипедов. А для некоторых тем вроде криптографии это вообще категорический императив.
Вы можете попробовать читать именно то что написано.
"Смысл в том, что по ссылке всегда объект" — исходя из Ваших же слов, именно тут и будет создан пустой объект.
Это не чьи-то слова — это ваши собственные идеи.
Совсем не факт что будет использован паттерн null object — у него есть существенные ограничения.
Когда null object все-таки применяется — нейтральный объект обычно создается статически и переиспользуется многократно.
Например, метод FindPerson вместо null (всеми почему-то ненавистного) вернет «пустой» объект, потому что null вернуть он не может.
Вы статью вообще прочитали? Недостатки реализации null в C# расписаны еще до ката.
С чего вы взяли что FindPerson должен использовать именно null object? Исключение при неудачном поиске бросить не судьба?
Позволяющих null ссылок заведомо меньше, чем их общее число, а на практике от силы процентов 5. Кроме того, при наличии ссылок без поддержки null проверку для каждого случая появления null достаточно сделать лишь однажды.
Лично для меня в такой логике ничего полезного нет, проверки на null остались, плюс добавились абсолютно бесполезные «пустые» объекты.
Вы сами предложили такую логику, не надо приписывать ее кому-то еще.
С диагностикой понятно — она всегда полезна. Анализ логов позволяет выделить часто встречающиеся проблемы и понять приоритет при исправлении. Да и сам поиск ошибок становится проще.
Логирование исключений в диагностических целях не требует перехвата и обработки именно NRE. Обычно делается хук на выброс исключения и логируется все подряд, за редким исключением. Для ошибок в коде разве что приоритет ставится FATAL.
Изоляция полезна всегда, когда у приложения много функций.
"Изоляция" при NRE — это попытка делать вид, что "все хорошо, прекрасная маркиза", при том, что о реальном состоянии системы вам известно только то, что воспроизвелась ошибка в коде.
Типовая реакция от VCL на этот случай годится только для тех приложений, ответственность за исправное функционирование которых невелика.
Опять-таки, это делается хуком c отловом всех необработанных исключений без специальной реакции конкретно на NRE.
Во всем остальном коде пытаться перехватить и обработать NRE значит стрелять себе же в ногу.
Я уточню, что речь идет об отлаженных приложениях. То есть NRE при выделении фразы — будет не на любой фразе, а на фразе со сложными знаками препинания, например с непарными кавычками. Тем самым мы сводим отказ от «программа вылетает» до «иногда не работает, но легко обходится». То есть понижаем важность исправления на 2 ступени.
Такая реакция — сладкая ложь для пользователя. Если ошибка и впрямь привязана к окружению и пользовательскому вводу, то перезапуск даст шанс их обойти, сохранив корректность работы. А вот продолжение работы с гарантированно поломанными инвариантами в надежде на "изоляцию" означает ненулевую вероятность действительно крупных неприятностей: от порчи важных данных и заведомо неудачных автоматических сделок на бирже до инъекции смертельной дозы обезболивающего.
Если вы не в курсе, самые опасные сбои в промышленной эксплуатации из-за ошибок в коде как раз редкие и плавающие. Частые и легко воспроизводимые чаще всего не доходят до боевой площадки, а если доходят, то легко исправляются.
У программ нет такого показателя как надежность. Есть корректность — отсутствие ошибок кодирования, есть отказоустойчивость — способность восстанавливаться после сбоев. Описанная вами методика при NRE дает иллюзию корректности с помощью иллюзии отказоустойчивости, по факту не обеспечивая ни того, ни другого.
В программе с высокой ценой сбоев, исключений, означающих ошибку в коде, не должно быть вообще. Для NRE этого добиться просто, для дедлоков — сложнее, но цель должна быть только такой. У меня был опыт доведения проекта, выдававшего по десятку страниц разных исключений вроде AV и т.п., до вылизанного состояния.
Вы спрашивали, избавит ли в C# от проверок добавка фичи из котлина и каким образом.
Да, от части проверок избавит — ссылочные типы без null соответсвуют решению 12 из статьи и позволяют не проверять их значения на null по построению.
Смысл обсуждать котлин в теме про C# простой:
Ссылочные типы без null всегда обсуждаются при разработке новых версий C#.
Котлин свободен от NRE, кроме случаев взаимодействия с внешним не-котлин кодом.
У JVM и Java проблема с null в точности та же что и в .NET и C#
У C# в сравнении с котлином есть дополнительное обременение в виде совместимости с предыдущими версиями языка.
Вы, возможно, спутали разные виды отказов. От NRE ваши способы 1-3 не помогают никак, 4-5 чуть лучше, но тоже ничего не гарантируют. Этим ошибки в коде кардинально отличается от сбоев в окружении, для обхода которых и придуманы ваши пять пунктов.
Самым обыкновенным — если тип не допускает null, то его значения проверять на null не нужно. Совсем как в котлине сделать не выйдет — обратная совместимость нужна.
Все (по крайней мере должны) проверяют входные параметры в функцию и выходные из функции.
Да, восемь строк проверки на три строки полезного кода смотрятся просто, чисто и элегантно.
Проверки выходных параметров и возвращаемых значений в коде не припоминаю за все время работы.
Посмотрите решение 11 — оно справится с проверками лучше программиста-человека.
в «исторической альтернативе» все как-то, извините, «сдулось» в один маленький абзац.
А там и не требуется сильно больше: источником серьезной проблемы стала экономия буквально на спичках. Добавил примеры кода к альтернативе.
Сухие перечисления без примеров — бесполезны, никто не будет «заучивать» их наизусть, без понимания почему так.
В этом случае каждое решение грозит превратиться в отдельную статью, что повысит трудоемкость для меня и ухудшит усвояемость для читателей.
Я не стремился подробно осветить каждый нюанс каждого частного случая. Моей задачей было дать обзор типовых проверенных решений и высокоуровневые критерии для их выбора. Для тех, кто хочет узнать больше о конкретном варианте — в тексте есть ссылки.
Совершенно верно. Заодно компилятор даст по рукам, тому кто попытается null туда запихнуть.
Совершенно верно. Только после первой же успешной проверки у меня будет значение ссылочного типа, не допускающего null и его, в отличие от нынешних, не надо будет проверять по всей глубине стека вызовов. Заодно компилятор даст по рукам тому, кто рискнет пропустить обязательную проверку.
Итоги:
98 год?
Да, все то, про что я думал как о лучших альтернативах, еще не существовало, даже файберы надо руками писать.
Дикий капитализм — цена разработки системы меньше чем недельная прибыль от ее эксплуатации, офигеть.
У меня нет такой статистики, к сожалению — я уже давно не работаю в той компании. Да и 10 лет тому проекту нет и сейчас. Условия тоже иные — требования по надежности менее жесткие, а вот унаследованного технического долга был вагон и маленькая тележка. Тем не менее от исключений, которые сами по себе означали ошибку в коде, мы избавились.
Речь ни в коем случае не идет об ликвидации всех ошибок! Я имею в виду только предотвращение тех из них, которые вызывают исключения, чей тип гарантированно означает ошибку в коде (не в окружении и не во входных данных).
Это исключение само по себе ошибку в коде не означает. Но в ваших условиях его цена понятна. Остальное из вашей четверки для меня всегда было уже некрологом.
Коммерческий опыт у меня начался с Delphi 7. Для младших версий FreeAndNil несложно написать самому. От формы (а в идеале от GUI вообще) исправность системы ИМХО зависеть не должна.
PS: Большая статья о вашей системе станет украшением любого тематического сайта.
Ну в опытной эксплуатации на фоне промышленной все наоборот — надо "ломать и крушить", давая нагрузки и условия заведомо жестче боевых.
"Всего лишь механизм транзакций" — это уже из серии "90% любой крупной программы на C++ представляет собой медленную и глючную реализацию подмножества спецификации Common Lisp" (по памяти).
Если нужны качества, которые может дать только безопасный рантайм — логично использовать готовый и проверенный безопасный рантайм вместо велосипедов. А для некоторых тем вроде криптографии это вообще категорический императив.
Вы можете попробовать читать именно то что написано.
Это не чьи-то слова — это ваши собственные идеи.
Вы сами предложили такую логику, не надо приписывать ее кому-то еще.
Так в эрланге и изоляция настоящая, и источник реально доверенный, и отказоустойчивость неиллюзорная.
Логирование исключений в диагностических целях не требует перехвата и обработки именно NRE. Обычно делается хук на выброс исключения и логируется все подряд, за редким исключением. Для ошибок в коде разве что приоритет ставится FATAL.
"Изоляция" при NRE — это попытка делать вид, что "все хорошо, прекрасная маркиза", при том, что о реальном состоянии системы вам известно только то, что воспроизвелась ошибка в коде.
Типовая реакция от VCL на этот случай годится только для тех приложений, ответственность за исправное функционирование которых невелика.
Опять-таки, это делается хуком c отловом всех необработанных исключений без специальной реакции конкретно на NRE.
Во всем остальном коде пытаться перехватить и обработать NRE значит стрелять себе же в ногу.
Если вы не в курсе, самые опасные сбои в промышленной эксплуатации из-за ошибок в коде как раз редкие и плавающие. Частые и легко воспроизводимые чаще всего не доходят до боевой площадки, а если доходят, то легко исправляются.
У программ нет такого показателя как надежность. Есть корректность — отсутствие ошибок кодирования, есть отказоустойчивость — способность восстанавливаться после сбоев. Описанная вами методика при NRE дает иллюзию корректности с помощью иллюзии отказоустойчивости, по факту не обеспечивая ни того, ни другого.
В программе с высокой ценой сбоев, исключений, означающих ошибку в коде, не должно быть вообще. Для NRE этого добиться просто, для дедлоков — сложнее, но цель должна быть только такой. У меня был опыт доведения проекта, выдававшего по десятку страниц разных исключений вроде AV и т.п., до вылизанного состояния.
Аргумент "вместо ошибки периода выполнения непонятно где и когда получаем ошибку периода компиляции по месту дефекта" вы тоже не увидели?
Вы спрашивали, избавит ли в C# от проверок добавка фичи из котлина и каким образом.
Да, от части проверок избавит — ссылочные типы без null соответсвуют решению 12 из статьи и позволяют не проверять их значения на null по построению.
Смысл обсуждать котлин в теме про C# простой:
В котлине есть ссылочные типы, не допускающие null. Им проверки на null не нужны по построению.
Вы, возможно, спутали разные виды отказов. От NRE ваши способы 1-3 не помогают никак, 4-5 чуть лучше, но тоже ничего не гарантируют. Этим ошибки в коде кардинально отличается от сбоев в окружении, для обхода которых и придуманы ваши пять пунктов.
Самым обыкновенным — если тип не допускает null, то его значения проверять на null не нужно. Совсем как в котлине сделать не выйдет — обратная совместимость нужна.
Да, не ту часть проблемы я обозначил как пушного зверька
Элементарно:
И создать себе геморрой еще и со значимыми типами.
Когда есть выбор между
результат немного предсказуем.
Да, восемь строк проверки на три строки полезного кода смотрятся просто, чисто и элегантно.
Проверки выходных параметров и возвращаемых значений в коде не припоминаю за все время работы.
Посмотрите решение 11 — оно справится с проверками лучше программиста-человека.
А что будет при тесном взаимодействии с любым Java-фреймворком?
А там и не требуется сильно больше: источником серьезной проблемы стала экономия буквально на спичках. Добавил примеры кода к альтернативе.
В этом случае каждое решение грозит превратиться в отдельную статью, что повысит трудоемкость для меня и ухудшит усвояемость для читателей.
Я не стремился подробно осветить каждый нюанс каждого частного случая. Моей задачей было дать обзор типовых проверенных решений и высокоуровневые критерии для их выбора. Для тех, кто хочет узнать больше о конкретном варианте — в тексте есть ссылки.