- PVSM.RU - https://www.pvsm.ru -
В этой статье мы коротко пройдемся по малоизвестным особенностям boxing/unboxing.
Предыдущая статья о foreach [1]
Предыдущая статья об Array [2]
Типичный вопрос на собеседовании об упаковке и распаковке выглядит следующим образом — «Что будет при запуске данного кода, и если он не будет работать то как его исправить?».
Тестовый код:
object box = (int)42;
long unbox = (long)box;
Ответ может быть следующий — «При распаковке первый оператор является не приведением типов а распаковкой типа, соответственно он должен соответствовать типу значения находящегося в запакованном виде.».
Правильный ответ:
object box = (int)42;
long unbox = (long)(int)box;
Обычно это считается правильным ответом, но это не совсем так…
Представьте себе удивление человека, когда вы ему напишете другой правильный вариант.
Второй правильный ответ:
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;
Распаковка поддерживает и 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<T> where T : struct
{
public bool HasValue { get; }
public T Value { get; }
}
Равнозначные записи:
Nullable<int> value;
int? value;
Всем спасибо за внимание!
Автор: mynameco
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/unboxing/70939
Ссылки в тексте:
[1] Предыдущая статья о foreach: http://habrahabr.ru/post/209914/
[2] Предыдущая статья об Array: http://habrahabr.ru/post/194626/
[3] Источник: http://habrahabr.ru/post/239219/
Нажмите здесь для печати.