Подтвердить что ты не робот

Почему тип, выброшенный или зараженный, вызывается из System.Exception

Так просто из любопытства я хотел посмотреть, что было особенным в классе исключений, что позволило использовать его с ключевым словом Throw, а стандартный класс - нет.

Все, что я обнаружил, это то, что класс Exception реализовал следующие

public class Exception : System.Object, System.Runtime.Serialization.ISerializable, System.Runtime.InteropServices._Exception
{
}

Итак, я попытался реализовать те же интерфейсы и попытался создать собственное собственное исключение, которое не получило от System.Exception безрезультатно. Мне просто сказали, что

Тип, пойманный или выброшенный, должен быть получен из System.Exception

Так есть ли какая-то конкретная причина для этого? Я предполагаю, что в управляемых языках так мало вариантов, как представляется, произвольно.

4b9b3361

Ответ 1

Я думаю, что ваше предположение ошибочно. Возможно, что объект брошен, который не получен из System.Exception. Вы просто не можете выбросить его на С# или изучить объект в предложении catch. Из раздела 8.10 спецификации С# (v4.0):

Некоторые языки программирования могут поддерживать исключения, которые не являются представляемый как объект, полученный из System.Exception, хотя такие исключения никогда не могут быть сгенерированы кодом С#. Общий улов может быть использовано для исключения таких исключений. Таким образом, общий улов предложение семантически отличается от того, которое указывает тип Исключение System.Exception, поскольку первое может также перехватывать исключения из другие языки.

Пример общего catch:

try
{
}
catch (Exception) { } // 'specific' catch
catch { } // 'general' catch

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

Некоторые типы всегда, кажется, получают особое лечение на каждом языке. В основном потому, что они настолько фундаментальны для системы. System.Exception, System.ValueType, System.Delegate - все специальные типы на С#, которые тесно связаны с языковыми ключевыми словами и CLR, поэтому неудивительно, что вы не можете просто реализовать классы, которые выполняют свои роли.

Ответ 2

Рекомендации по дизайну исключений

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

throw (ссылка С#)

Исключенное исключение - это объект, класс которого получен из System.Exception, как показано в следующем примере.

class MyException : System.Exception {}
// ...
throw new MyException();

Обзор исключений

В .NET Framework исключение - это объект, который наследуется от класс исключения

Итак, ваше исключение должно происходить из System.Exception, но это зависит от вас, как вы его организуете.

Ответ 3

Язык использует System.Exception как базу для всех исключений. Это по существу означает, что любое броское или захватывающее исключение не должно выходить из строя, если вы выполняете (Exception)myExc. Вероятно, это связано с тем, что определение класса System.Exception используется таким образом, чтобы все исключения придерживались одного и того же интерфейса. Из-за согласованного интерфейса исключения поступают с трассировкой стека и значимым сообщением (например), что неоценимо для ведения журнала.

Ответ 4

Это произвольный выбор дизайнеров CLS. Предположительно, они сделали этот выбор по соображениям последовательности. С# следует за CLS; это требование выполняется компилятором по этой причине, а не по какой-либо технической причине, связанной с реализацией типа исключения.

CLI может фактически выбросить любой объект. См. http://jilc.sourceforge.net/ecma_p3_cil.shtml#_Toc524462405.

Ответ 5

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

Если у меня есть это:

try
{
    ...
}
catch(Exception ex)
{
    // Handle somehow
}

Это будет ломать ВСЕ исключения и позволит мне отображать, что это (с помощью ex.Message).

Если вы можете что-то бросить, то как у вас будет улов, который поймает все и все-таки даст вам доступ к брошенному объекту?

У вас может быть это, что поймает абсолютно все:

try
{
    ...
}
catch
{
    // Handle somehow
}

Но вы "потеряли" то, что было брошено.