CLR: если конструктор потерпит неудачу, он всегда будет выдавать исключение? - PullRequest
1 голос
/ 28 июня 2009

В Delphi, если во время создания объекта возникло исключение: любая выделенная память будет освобождена и будет сгенерировано исключение. Например, следующее было гарантировано , чтобы либо вернуть действительный объект Camera, либо выдать исключение:

Camera c = new Camera();

Вы никогда не должны были проверять результирующую переменную на нулевое значение:

Camera c = new Camera();
if (c == null)
   throw new Exception("Error constructing Camera") //waste of time

То же самое верно в CLR?

И есть ли другие синтетические конструкции, в которых возвращаемое значение гарантированно либо будет действительным, либо выдает исключение?

  • Создание структур (например, прямоугольник)?
  • получить член перечисления?
  • результат Object.ToString ()?
  • математические операции?

В случае выполнения математики:

Int32 aspect = 1650.0 / 1080.0;
if (aspect == null) 
   throw new Exception("Division of two numbers returned null")

Ответы [ 2 ]

3 голосов
/ 28 июня 2009

Конструктор в .Net гарантированно возвращает ненулевой экземпляр типа объекта. Независимо от того, является ли экземпляр допустимым , зависит от индивидуальной семантики типа.

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

Что касается других упомянутых вами случаев

  • Создание структур: структуры по определению не могут быть нулевыми. Исключения, сгенерированные в конструкторе, будут нормально распространяться
  • Получение члена перечисления: перечисления являются типами strutures / value и не могут быть нулевыми
  • результат Object.ToString (): это может (и, к сожалению, будет) быть нулевым. String является ссылочным типом, и вполне допустимо возвращать null из переопределения ToString (пожалуйста, не делайте этого).
  • Математические операции: это сильно зависит как от настройки переполнения вашего проекта, так и от конкретного используемого типа (целочисленная или с плавающей запятой).

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

float f1 = 1.0;
float f2 = f1 / 0;

В этот момент f2 является очень специфическим значением с плавающей точкой, которое не представляет действительное число. Это действительно? Зависит от вашего варианта использования.

1 голос
/ 28 июня 2009

Да. Я хотел бы выразить это так (поскольку fail может означать логический сбой тоже): если конструктор не выдает исключение, возвращаемое значение гарантированно не будет null так что вам никогда не придется выполнять такую ​​проверку.

Создание структур (например, прямоугольник): struct вообще не может быть null (Nullable типы считаются совершенно разными типами, т.е. typeof(int?) != typeof(int)). Вызов конструктора для структуры может привести к ошибке, вызвав исключение, или вернуть экземпляр.

Получение члена перечисления: enum - это просто набор констант. Нет ничего лучше, чем «получить член во время выполнения». Он подставляется во время компиляции.

Результат Object.ToString(): Как и любой метод, он может вернуть любое допустимое значение для типа string, который включает null, а также может вызвать исключение (в этом случае он вообще не возвращает значение ).

Математические операции: все выражения возвращают значение или выдают исключение. Возвращаемое значение может быть любым допустимым значением для этого типа (например, Int32 никогда не может быть null).

...