С# кастинг для типа NULL?
Вне обычная расточная разность между Cast
и As
- Если я знаю, что яблоко - это Фрукты, поэтому я могу использовать
(Fruit)apple
- и он выдает исключение, если оно aint
-
as value
может быть проверен с помощью null, чтобы увидеть, удалось ли [исключить исключение...]
Однако я читал @EricLippert статью об этом, и был хороший пример о типах Nullable Value:
short? s = (short?)123;
int? i = s as int?;
это не скомпилируется...
Невозможно преобразовать тип 'short?' to 'int?' посредством преобразования ссылок, преобразования бокса, преобразования для распаковки, преобразования конверсий или преобразования нулевого типа
Fine.
так почему это:
short? s = (short?)123;
int? i = (int?)s;
Скомпилирует? (Против всех ожиданий! я ЗНАЕТ, что s
не int?
- и он должен идти BANG, но он не...)
проверка трансляции здесь должна быть намного более смертельной, чем предыдущий пример (который ушел в Bang)
Я плохо себя чувствую, спрашивая об этом многословном предмете.
Спасибо в Advance.
Ответы
Ответ 1
В первом примере оператор as
пытается использовать объект s
как int?
. Поскольку int?
не существует в цепочке наследования short?
, эта операция не выполняется.
В вашем втором примере вы фактически создаете новый int? i
со значением от short? s
. Это более щедрая операция, потому что ей не нужно сохранять исходный объект s
с левой стороны.
Важным моментом здесь является то, что as
не разрешено делать что-либо, что не сохраняет ваш идентификатор объекта. Явное литье может.
Здесь, что стандарт С# говорит о том, как работает форма (int?)
:
6.1.4 Неявные преобразования с нулевым значением
Предопределенные неявные преобразования, которые работают с непустым значением типы также могут использоваться с обнуляемыми формами этих типов. Для каждого из предопределенные неявные идентификационные и числовые преобразования, которые конвертируют от значения типа N, не имеющего значения NULL, к типу T с непустым значением, следующие неявные преобразования с нулевым значением:
· Неявное преобразование из S? к Т?.
· Неявное преобразование из S в T?.
Оценка неявного преобразования с нулевым значением на основе базового преобразование из S в T происходит следующим образом:
. Если нулевое преобразование происходит от S? к T?:
o Если исходное значение равно null (свойство HasValue является ложным), результатом является нулевое значение типа T?.
o В противном случае преобразование оценивается как разворот с S? в S, за которым следует базовое преобразование из S в T, за которым следует (§4.1.10) от T до T?.
. Если нулевое преобразование от S до T?, преобразование оценивается как базовое преобразование из S в T, за которым следует обертывание из T в T?.
Ответ 2
Пример:
int? i = (int?)s;
Скомпилирован ли компилятор, потому что вы рассказываете компилятору, что знаете то, что он не может вывести, т.е. что s
можно преобразовать в int?
.
Вы получите только исключение во время выполнения, если приведение не выполнено.
Ответ 3
Я думаю, что это может привести к ошибке as
, вам будет предоставлен "действительный" результат null
, поэтому значение false. Во втором случае бросок допускается в случае сбоя, он вызывает исключение.
Ответ 4
Причина в том, что int? является просто сокращением для System.Nullable<int>
(System.Nullable<T>
- тип). Короткий тип определяет явное приведение к int, однако System.Nullable<T>
не имеет такого явного приведения, поскольку T может быть любым другим типом значения.