Почему исключения отсутствуют в .NET?


41

Я знаю, Google Googling Я могу найти подходящий ответ, но я предпочитаю слушать ваши личные (и, может быть, технические) мнения.
В чем основная причина разницы между Java и C# при метании исключений?
В Java подпись метода, который генерирует исключение, должна использовать ключевое слово «throws», а в C#, которое вы не знаете во время компиляции, если может быть выбрано исключение.

44

Поскольку ответ на проверяемые исключения почти всегда:

try { 
    // exception throwing code 
} catch(Exception e) { 
    // either 
    log.error("Error fooing bar",e); 
    // OR 
    throw new RuntimeException(e); 
} 

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

+4

Но на самом деле, это не должно быть. Множество исключений не являются фатальными. Основная проблема заключается в том, что Checked, вероятно, не должен быть типом исключения по умолчанию, и они злоупотребляются на Java. Но проверенные исключения могут быть полезны. 26 сен. 082008-09-26 20:11:22

+8

Если программист ленив, как эта ошибка Java? Если программист их использует, то это плохой дизайн API, и опять же, как эта ошибка Java? Изгиб языка назад, чтобы успокоить лень или глупость, никогда не является хорошей идеей в моей книге. Я, например, считаю, что проверенные исключения являются полезным ИНСТРУМЕНТОМ, не более того, не что иное, как 28 сен. 092009-09-28 16:46:06

+23

@mcjabberz, JDK излишним их. Это ошибка Java. 30 сен. 092009-09-30 17:49:50

  0

Ява полна догм. 24 апр. 142014-04-24 11:19:50

+1

Некоторое время я хочу, чтобы C# создало предупреждение, если я не поймаю исключение в своем коде. это облегчит жизнь. 10 сен. 172017-09-10 09:19:09


13

Основная философия дизайна C# заключается в том, что на самом деле отлавливание исключений редко бывает полезным, тогда как очистка ресурсов в исключительных ситуациях весьма важна. Я считаю справедливым сказать, что using (шаблон IDisposable) является их ответом на проверенные исключения. Подробнее см. В [1].

  1. http://www.artima.com/intv/handcuffs.html

1

Я перешел с Java на C# из-за смены работы. Сначала меня немного беспокоило разницу, но на практике это не изменило ситуацию.

Возможно, это потому, что я пришел из C++, у которого есть объявление об исключении, но оно обычно не используется. Я пишу каждую строку кода, как если бы ее можно было выбрасывать - всегда используйте, используя «Одноразовый», и думайте об очистке, которую я должен сделать в конце.

В ретроспективе распространение объявления бросков в Java на самом деле ничего не принесло мне.

Мне хотелось бы сказать, что функция определенно никогда не бросает - я думаю, что это было бы более полезно.

+2

Существует ограниченная степень, в которой функция может сказать это ** определенно ** никогда не бросает - например, ситуация с низкой памятью может привести к исключению OutOfMemoryException почти где угодно, например. Может быть, функция может требовать, чтобы она никогда не бросала «преднамеренно», но насколько это было бы полезно? Что вы могли бы с пользой сделать с таким требованием? 12 июн. 092009-06-12 15:26:04


1

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


10

К тому времени .NET был разработан, Java проверил исключения в течение достаточно долгого времени, и эта функция рассматривалась разработчиками Java в лучшем случае, как controversialcontroversial. Таким образом, разработчики .NET chose не должны включать его на языке C#.

  0

выглядит смешно, но я думаю, что это правда и является одной из главных причин того, что команда языка дизайна C# никогда не расскажет нам :) 18 май. 122012-05-18 17:38:32

  0

выглядит как ссылка andersnoras.com сломана 30 сен. 152015-09-30 04:21:56


4

Интересно, что ребята из Microsoft Research добавили отмеченные исключения в Spec#, их надмножество C#.

+2

Так как мне не хватает репутации чтобы отредактировать ответ, вот ссылка на speC# info: http://research.microsoft.com/SpecSharp/ 23 сен. 082008-09-23 22:38:33


1

Я иногда пропускаю проверенные исключения в C# /. NET.

Я полагаю, кроме Java нет другой заметной платформы. Возможно, ребята .NET просто пошли с потоком ...

+1

Проблема в том, что очень немногие программисты фактически используют проверенные исключения, как они были разработаны. Это случай идеальной практики. Идеально проверенные исключения очень полезны, но на практике они в основном добавляют дополнительную работу для программиста. 23 сен. 082008-09-23 22:56:14

+3

Следующие идеальные практики берут идеальных программистов. 23 сен. 082008-09-23 23:27:39

+1

@Constantin: ... или класс или два в дизайне API 28 сен. 092009-09-28 16:49:59


92

В статье The Trouble with Checked Exceptions и Хейлсберг (в конструкторе C# языка) собственный голос, есть три основные причины для C#, не поддерживающие проверяемых исключений, как они будут найдены и проверены в Java:

  • Нейтральный на проверяемые исключения

    «C# в основном молчит по проверяемому вопросу исключений. После того, как лучше решения известно, и поверьте мне, мы продолжать думать об этом, мы можем пойти назад и фактически положить что-то в месте.»

  • Versioning с проверяемыми исключениями

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

    «Это смешно, как люди думают, что важной вещь исключений обращения с ними. Это не относится к исключениям. В хорошо написанном приложении есть соотношение от десяти до одного, на мой взгляд, попробуйте, наконец, попробовать поймать. Или в C#, using заявления, которые как попытаться наконец-то.»

  • Масштабируемость проверяемых исключений

    «В малом, проверил исключения очень заманчиво ... Беда начинается, когда вы начинаете строить большие системы , где вы разговариваете с четырьмя или пятью различными подсистемами. Каждая подсистема выбрасывает от четырех до десяти исключений . Теперь, каждый раз, когда вы поднимаетесь на на лестницу агрегирования, у вас есть эта экспоненциальная иерархия ниже вас исключений, с которыми вам приходится иметь дело. Вам нужно объявить 40 исключениями, которые вы можете бросить. ... Это просто воздушные шары из-под контроля.»

В своей статье„Why doesn't C# have exception specifications?“, Anson Horton (Visual C# Программа Manager) также перечисляет следующие причины (см статью подробности о каждой точке):

  • управления версиями
  • Производительность и качество кода
  • Непривлекательность при наличии автогражданской квалификации между проверено и unchecked исключений
  • Сложность определения правильных исключений для интерфейсов.

Интересно отметить, что C# делает, тем не менее, поддерживает документацию исключений брошенных данный метода с помощью <exception> тега и компилятор даже берет на себя труд проверить, что тип ссылки исключения действительно существует. Тем не менее, на сайтах вызовов не используется проверка или использование метода.

Вы также можете посмотреть в Exception Hunter, который является Commerical инструмента, с помощью Red Gate Software, который использует статический анализ, чтобы определить и сообщить исключения, метод и которые потенциально могут пойти неперехваченным:

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

Наконец, Bruce Eckel, автор Thinking in Java, есть статья под названием «Does Java need Checked Exceptions?», что может быть стоит читать вверх, а потому вопрос о том, почему проверяемые исключения не существует в C# обычно укореняется в сравнениях для Java ,

  0

Я полностью продаюсь на * Версии с проверенными исключениями * и * Версии с проверенными исключениями *. 20 дек. 092009-12-20 14:45:45

+2

Интересно, что, по моему опыту, многие разработчики склонны игнорировать «Как только лучшее решение известно» - часть. Теперь, в 2015 году, почти через 12 лет после этого заявления, я не видел никакого «лучшего решения» на C# или на любом другом языке, таком как Kotlin и т. Д. (Или я пропустил это? Я больше не программирую на C#.) И просто удаляя проверенные исключения без лучшего решения, думает хуже, ИМХО, не лучше. У нас было плохое время в одном из наших C# -приложений после некоторых рефакторингов, чтобы проверить, правильно ли обработаны исключения во всех случаях, потому что компилятор не сказал бы. 01 июн. 152015-06-01 10:33:17

  0

С версией ответа было бы просто не бросать проверенное исключение в новую версию, если это абсолютно необходимо. Я бы не согласился и сказал, что Java молчат на проверенных исключениях и C# упрям. И.Е. Java позволяет бросать проверенное исключение или время выполнения, но оставляет решение до вас, тогда как C# заставляет вас бросать исключение во время выполнения. Похоже, его аргумент сводится к тому, что «проверенные исключения злоупотребляют, поэтому мы не позволим вам их использовать». 17 окт. 162016-10-17 15:06:47

+1

Это должен быть принятый ответ. 06 сен. 172017-09-06 15:24:41

  0

, если IDE или компилятор создают предупреждение об исключениях, которые не обрабатываются программистом, они делают программное обеспечение более надежным и уменьшают ошибки времени выполнения. 10 сен. 172017-09-10 09:24:27


8

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

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

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

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

+1

+1. Проверяемая функция должна быть функцией отношения между сайтами вызова и уловов. Многие методы указывают, что определенные исключения используются вместо возврата при возникновении особых неожиданных условий. Например, 'IDictionary.Add() 'указывает, что реализация должна бросать' ArgumentException', если ключ уже существует. К сожалению, невозможно отличить исключение, которое по этой причине вызывается из «ArgumentException», которое вызывается методом, вызванным реализациями Dictionary.Add(), в обстоятельствах, которые он не ожидал. 29 окт. 122012-10-29 20:04:01

+1

Если бы я разрабатывал систему исключений, у меня было бы несколько дискретных (возможно, запечатанных) системных типов исключений, но не использовать типы исключений в качестве основного средства решения, что нужно уловить. Вместо этого у меня бы был объект исключения, который переносит один или несколько объектов абстрактного класса ExceptionInfo. Исключение, созданное 'IDictionary.Add', может начинаться как« ExpectedException », содержащее' DuplicateKeyExceptionInfo', но если оно просачивается через слой, который его не ожидал, он превратился бы в «UnexpectedException», в котором находился тот же объект. 29 окт. 122012-10-29 20:11:17

  0

Проверенные исключения могут быть злоупотреблены, но я бы ответил, что может быть трудно понять, какие исключения выбрасываются функцией в C#. заставляя разработчиков делать catch (исключение) ... что также является грехом. Если C# или Visualstudio обеспечили способ увидеть, какие исключения могут быть выбраны, я бы согласился с тем, что unchecked - путь. 17 окт. 162016-10-17 15:16:32


2

сам Андерс отвечает на этот вопрос this episode из программного обеспечения радиотехника подкаста