Интересные моменты в C# (boxing unboxing)
В этой статье мы коротко пройдемся по малоизвестным особенностям boxing/unboxing.Предыдущая статья о foreachПредыдущая статья об Array
Типичный вопрос на собеседовании об упаковке и распаковке выглядит следующим образом — «Что будет при запуске данного кода, и если он не будет работать то как его исправить?».
Тестовый код:
object box = (int)42; long unbox = (long)box; Ответ может быть следующий — «При распаковке первый оператор является не приведением типов, а распаковкой типа, соответственно он должен соответствовать типу значения находящегося в запакованном виде.».Правильный ответ:
object box = (int)42; long unbox = (long)(int)box; Обычно это считается правильным ответом, но это не совсем так…Unboxing и Enum Представьте себе удивление человека, когда вы ему напишете другой правильный вариант.Второй правильный ответ:
public enum EnumType { None } … object box = (int)42; long unbox = (long)(EnumType)box; Напомню, enum не является фундаментальным типом и не наследует его, он является структурой содержащей фундаментальный тип (базовый). Это говорит о том что в .NET есть явная поддержка такой распаковки. Так же легко проверить что распаковка не использует операторы явного и неявного преобразования и интерфейс IConvertible и свой тип не получится развернуть из чужого типа.При распаковке enum’а используется его базовый тип и следующая распаковка не будет работать.Неправильный вариант:
public enum EnumType: short { None } … object box = (int)42; long unbox = (long)(EnumType)box; Распаковка для enum’ов ослаблена предельно.Распаковываем int из enum’а:
public enum EnumType { None } … object box = EnumType.None; long unbox = (long)(int)box; Распаковываем один enum из другого: public enum EnumType { None } public enum EnumType2 { None } … object box = EnumType.None; long unbox = (long)(EnumType2)box; Unboxing и Nullable Распаковка поддерживает и Nullable типы, что кажется более логичным.Распаковка Nullable типа из обычного:
object box = (int)42; long unbox = (long)(int?)box; Распаковка обычного типа из Nullable: object box = (int?)42; long unbox = (long)(int)box; Напомню что Nullable это структура с одним обобщенным типом значения и предназначена для хранения данных и флага присутствия данных. Это говорит о том что в C# есть явная поддержка распаковки Nullable типов. В новых версиях C# для этой структуры появился alias »?».Nullable:
public struct Nullable