2012-04-08 2 views
25

За регулярной скучной разницей между Cast и AsC# casting to nullable type?

  • если я знаю, что яблоко является Fruit так что я могу использовать (Fruit)apple - и он бросает исключение, если он AINT
  • as value может быть проверен против нуля, чтобы убедиться, что удалось [не будет выбрасывать исключение ...]

Однако Ive читал @EricLippert article об этом и был хороший пример о Nullable Значение Типы:

short? s = (short?)123; 
int? i = s as int?; 

это не будет ... компиляции

Не удается преобразовать тип «короткий? ' to 'int?' через конвертацию ссылок, преобразование бокса, преобразование конвертирования, конвертирование упаковки или преобразование нулевого типа

Изобразительное.

так почему это:

short? s = (short?)123; 
    int? i = (int?)s; 

ли Compile? (! Вопреки всем ожиданиям Я ЗНАТЬ что s не int? - и он должен идти BANG но Эйнт ...)

отлитого проверки здесь должен быть гораздо более опасным, чем бывший пример (который пошел взрыв)

Я чувствую себя плохо, спрашивая об этом разговорном предмете.

Спасибо заранее.

+1

Вы точно описали то, что написал Эрик Липперт - компиляция будет выполняться, в то время как оператор 'as' не будет использоваться для случаев, касающихся типов с нулевым значением. – Yahia

+0

@Yahia, но мы согласны с тем, что короткий не является INT? –

+0

short is not int BUT может быть преобразован/преобразован в int - и это то, что вы говорите компилятору: сделайте это короткое int. – Yahia

ответ

23

В вашем первом примере оператор as пытается использовать объект s как int?. Поскольку int? не находится в цепочке наследования short?, эта операция не выполняется.

В вашем втором примере вы фактически создаете новый int? i со значением от short? s. Это более щедрая операция, потому что ей не нужно сохранять исходный объект s с левой стороны.

Важным моментом здесь является то, что as не имеет права делать что-либо, что не сохраняет личность вашего объекта. Явное приведение может.

Вот что # стандарт C говорит о том, как (int?) формы работы:

6.1.4 Неявного обнуляемого преобразование

Предопределенных неявных преобразования, которые работают на ненулевом значении также могут быть использованы типов с нулевыми формами этих типов. Для каждого из предопределенного неявное идентичность и числовые преобразования, которые преобразуют из ненулевых типа значения S к не-обнуляемому типу значения T, существует следующих неявное обнуляемое преобразования:

· неявное преобразование из S? к Т ?.

· Неявное преобразование из S в T ?.

Оценка неявного обнуляемого преобразования на основе базового преобразования из S в T протекает следующим образом:

· Если обнуляемое преобразование из S? to T ?:

o Если исходное значение равно null (свойство HasValue является ложным), результатом является нулевое значение типа T ?.

o В противном случае преобразование оценивается как разворот с S? до S, за которым следует базовое преобразование из S в T, за которым следует обертка (§ 4.1.1.10) от T до T ?.

· Если преобразование с нулевым значением составляет от S до T?, Преобразование оценивается как базовое преобразование из S в T, за которым следует упаковка от T до T ?.

+0

за пределами этого объяснения theres все еще эта строка '(int?) S', которые относятся к наследству/эпохе бокса .... но это работает, и это то, что я не понимаю. –

+0

@RoyiNamir, я действительно не понимаю. Преобразование существует из 'short' в' int' (это верно в C, Java и почти везде), а спецификация C# описывает, как принять это преобразование и заставить его работать с типами NULL. (Я добавил соответствующую выдержку выше.) – sblom

+1

@sblom Я думаю, вам следует «сделать двойной смел» в абзаце выше, говоря «Важным моментом здесь является то, что, как не разрешено делать что-либо, что не сохраняет личность вашего объекта. Явный актерский состав. - Я думаю, что это ядро. А что касается возможности кастинга, я согласен, это ясно для меня («как» на самом деле не было), и, поскольку Эрик сказал, что на коротких сессиях нет арифметики (на самом деле это не важно, но это легче понять, меня, по крайней мере, преобразования), он преобразуется в int. – NSGaga

3

Пример:

int? i = (int?)s; 

ли компилятор, потому что гипсовый ты говоришь компилятор, что вы знаете что-то, что он не может сделать вывод, что в том, что s может быть преобразован в int?.

Вы получите только исключение во время выполнения, если бросок не будет успешным.

+2

там нет Исключения во время выполнения ..... –

+0

@RoyiNamir - Извините, должен был добавить, что только в случае, если актер не работает. – Oded

0

Я думаю, что причина в случае as отказа вам будет дан «правильный» null результата, поэтому ложноположительного. Во втором случае приведение в действие допускается в случае отказа, оно вызывает исключение.

0

Причина в том, что int? является только сокращением для System.Nullable<int> (System.Nullable<T> - это тип). Короткий тип определяет явное приведение в int, однако System.Nullable<T> не имеет такого явного приведения, поскольку T может быть любым другим типом значения.