31 окт. 2009 г.

В чём разница между операторами «as» и «приведения»?

Никогда не задумывался над этим вопросом. Хотя всегда использовал приведение типов. А вот прочёл в переводном блоге Эрика Липперта, что приведение типов в случае невозможности приведения генерирует исключение. Оператор же as в случае неудачи возвращает NULL. То есть он требует оперирования nullable-типами. В общем - вот копипаст с заметки:


Большинство людей скажут, чт о разница между «(Alpha)bravo» и «bravo as Alpha» в том, что первое бросает исключение при неуспехе преобразования, а последнее возвращает null. Хоть это и правильно, и это самая очевидная разница, дело не только в этом. Здесь есть ловушки, которых нужно остерегаться.

Во-первых, поскольку результатом оператора «as» может быть null, целевым может быть только такой тип, который допускает значение null: либо ссылочный тип, либо Nullable тип-значение. Нельзя сделать «as int», это не имеет никакого смысла. Если аргумент не int, то каким должно быть возвращаемое значение? Выражение «as» всегда возвращает указанный тип, так что он должен быть типом, допускающим null.

Во-вторых, оператор приведения, как я уже обсуждал – странный зверёк. Он имеет два противоречивых смысла: «проверь, что этот объект действительно этого типа, брось исключение, если не так», и «этот объект не этого типа; найди мне эквивалентное значение, которое принадлежит этому типу». Второе значение оператора приведения не поддерживается оператором «as». Если вы написали

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

то вам не повезло. Оператор «as» не станет делать изменяющие представление преобразования из short в nullable int, как стал бы оператор приведения. Аналогично, если у вас есть класс Alpha и несвязанный с ним класс Bravo, с пользовательским оператором преобразования из Bravo в Alpha, то «(Alpha)bravo» применит это преобразование, а «bravo as Alpha» – нет. Оператор «as» учитывает только ссылочные преобразования, и упаковку/распаковку типов-значений.

И, в-последних, сценарии использования этих двух операторов, конечно же, имеют поверхностное сходство, но весьма различны семантически. Приведение сообщает читателю «я уверен, что это преобразование законно, и я готов получить исключение при исполнении, если я ошибся» Оператор «as» сообщает «Я не знаю, можно ли провести это преобразование; мы дадим ему шанс, и посмотрим, что получилось».

Комментариев нет:

Отправить комментарий