Почему FormatException не наследуется от ArgumentException? - PullRequest
8 голосов
/ 25 января 2010

Есть ли известная причина, по которой FormatException не наследуется от ArgumentException? Неверный формат может показаться очень специфическим случаем аргумента, который является недействительным, подобно ArgumentOutOfRangeException.

В статье MSDN для класса говорится:

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

Звучит как сценарий для ArgumentException или производного класса для меня.

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

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

Ответы [ 2 ]

13 голосов
/ 25 января 2010

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

Например, BinaryReader.Read7BitEncodedInt сгенерирует FormatException, если то, что он собирается прочитать из потока, не является допустимым 7-битовым кодированным целым числом. Это не требует никаких аргументов вообще. ArgumentException, с другой стороны, должен генерироваться, только если аргумент, переданный в качестве формального параметра методу, недопустим.

Описание, на которое вы ссылаетесь из статьи MSDN, является более ограничительным, чем FormatException на самом деле и должно быть разъяснено.

5 голосов
/ 25 января 2010

Это немного сопливо: но Рихтер из CLR Via C # (стр. 432) предполагает, что, возможно, это потому, что иерархия исключительных классов не очень хорошо реализована в .NET:

Первоначальная идея Microsoft заключалась в том, что System.Exception будет базовым типом для всех исключений, а два других типа, System.SystemException и System.ApplicationException, будут единственными двумя типами, непосредственно полученными из Exception. Кроме того, исключения, создаваемые CLR, будут получены из SystemException, а все исключения, создаваемые приложением, будут получены из ApplicationException. Таким образом, разработчики могут написать блок catch, который перехватывает все исключения приложения.

Однако ... это правило не очень хорошо соблюдалось; некоторые исключения являются непосредственными производными от Exception (IsolatedStorageException), некоторые сгенерированные CLR исключения извлекаются из ApplicationException ... Так что это большой беспорядок, и в результате получается, что типы SystemException и ApplicationException не имеют никакого особого значения вообще. На данный момент Microsoft хотела бы удалить их из иерархии классов исключений, но они не могут, потому что это нарушит любой код, который уже ссылается на эти типы.

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

...