бокс и распаковка в int и string - PullRequest
8 голосов
/ 21 июня 2011

Я немного запутался в боксе и распаковке. Согласно его определению

Бокс - это неявное преобразование ValueTypes в ссылочные типы (объект).
UnBoxing - это явное преобразование ссылочных типов (объектов) в эквивалентные значения типа.

лучший пример для описания этого -

int i = 123; object o = i;  // boxing

и

o = 123; i = (int)o;  // unboxing 

Но мой вопрос в том, является ли int типом значения, а строка ссылочным типом, поэтому

int i = 123; string s = i.ToString();

и

s = "123"; i = (int)s; 

Это пример бокса и распаковки или нет ???

Ответы [ 4 ]

20 голосов
/ 21 июня 2011

Звонить ToString это не бокс.Он создает новую строку, которая просто содержит текстовое представление вашего int.

При вызове (object)1 это создает новый экземпляр в куче, который содержит int.Но это все еще int.(Вы можете проверить это с помощью o.GetType())

Строка не может быть преобразована с приведением к int.Таким образом, ваш код не будет компилироваться.

Если вы сначала приведете свою строку к object, ваш код будет скомпилирован, но потерпит неудачу во время выполнения, так как ваш объект не упакован в int.Вы можете распаковать только тип значения в точно правильный тип (или связанный с ним обнуляемый).

Два примера:

Broken:

object o=i.ToString();// o is a string
int i2=(int)o;//Exception, since o is no int

Работает:

object o=i;// o is a boxed int
int i2=(int)o;//works 
2 голосов
/ 21 июня 2011
 int i = 2;
 string s = i.ToString();

Это НЕ бокс.Это просто вызов метода Int32.ToString(), который возвращает отформатированную строку, представляющую значение int.

 i = (int)s;

. Этот код не будет компилироваться, так как не существует явного преобразования, определенного между System.String иSystem.Int32.

Подумайте об этом следующим образом, чтобы понять, что есть, а что нет бокс и распаковка :

  1. Бокс: это когда вы берете тип значения и просто «втыкаете» его в ссылочную переменную.Для этой операции не требуется никакой логики преобразования, специфичной для типа.Тип переменной останется прежним, если вы используете GetType().

  2. Распаковка: это просто противоположная операция.Возьмите тип значения, застрявший в ссылочном объекте, и назначьте его переменной типа значения.Опять же, нет необходимости в какой-либо логике преобразования, специфичной для типа, чтобы эта операция работала.

    Поэтому, если бы (int)s было допустимым, это было бы просто явное преобразование, а не операция распаковки потому что s.GetType() вернет System.String, а не System.Int32.

0 голосов
/ 30 декабря 2012

Опоздал на вечеринку по этому поводу, но ...... Мне не нравится просто читать ответы и без доказательств за ними. Мне нравится понимать проблему, анализировать возможное решение и смотреть, связано ли оно с моим пониманием. Это копирование и вставка текста из по достоинству признанного превосходного «CLR via C #» бога Джеффа Рихтера объясняет это:

Несмотря на то, что у незаписанных типов значений нет указателя на объект типа, вы все равно можете вызывать виртуальные методы (такие как Equals, GetHashCode или ToString), унаследованные или переопределенные типом. Если ваш тип значения переопределяет один из этих виртуальных методов, то CLR может вызывать метод не виртуально, потому что типы значений неявно запечатаны и не могут иметь никаких производных от них типов. Кроме того, экземпляр типа значения, используемый для вызова виртуального метода, не упакован. Однако, если ваше переопределение виртуального метода вызывает реализацию метода базового типа, то экземпляр типа значения блокируется при вызове реализации базового типа, так что ссылка на объект кучи передается указателю this в базу метод. Однако для вызова не виртуального унаследованного метода (такого как GetType или MemberwiseClone) всегда требуется, чтобы тип значения был упакован, поскольку эти методы определены System.Object, поэтому методы ожидают, что аргумент this будет указателем, который ссылается на объект куча.

Мистер Рихтер должен получить медаль за эту книгу. Если у вас его нет, то получите !! Тогда вы получите:)

0 голосов
/ 21 июня 2011

Упаковка / распаковка: преобразование типов значений в представление объекта и наоборот (например, int и object).

Метод ToString (), напротив, является операцией, которая сгенерировала новую строку, и не имеет ничего общего с боксом / приведением / типом разговора.

...