CLR:Если конструктор выходит из строя, всегда ли он будет выдавать исключение?

StackOverflow https://stackoverflow.com/questions/1054218

  •  20-08-2019
  •  | 
  •  

Вопрос

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

Camera c = new Camera();

Ты никогда пришлось проверить результирующую переменную на null:

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")
Это было полезно?

Решение

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

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

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

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

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

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

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

Другие советы

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

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

Получение элемента перечисления:Ан enum это просто набор констант.Нет ничего лучше "получения элемента во время выполнения". Он заменяется во время компиляции.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top