Что именно происходит, когда я выполняю приведение типов ссылок и значений - PullRequest
3 голосов
/ 06 мая 2010

Что именно происходит, когда я выполняю приведение к ссылочным типам и типам значений и наоборот (боксирование и распаковка) на уровне компилятора или среды выполнения? Может ли какой-либо орган объяснить следующие четыре условия? Пожалуйста, не стесняйтесь добавлять условия, если я что-то пропущу.

 1. Stream stream = new MemoryStream();
    MemoryStream memoryStream = (MemoryStream) stream;
 2. double k=10.0;
    int l = (int)k;
 3. object k =20;
    int l = (int)k;
 4. int k =23;
    double m = k;

1 Ответ

4 голосов
/ 06 мая 2010

Здесь происходит три типа конверсий:

Преобразование 1 является справочным преобразованием. CLR проверит, что значение stream равно на самом деле ссылка на MemoryStream (или подтип), а затем просто скопирует ссылку в memoryStream. Новые объекты не создаются или что-то в этом роде. После этого и stream, и memoryStream относятся к одним и тем же объектам. Значения двух переменных в памяти будут одинаковыми.

Преобразования 2 и 4 являются числовыми преобразованиями - они переходят из одной числовой формы в другую. Это в основном операция типа FPU. Преобразование 2 является явным (поскольку оно может потерять информацию), тогда как преобразование 4 является неявным, но в основном они похожи в том, что они оба изменяют фактические представления.

Преобразование 3 является операцией распаковки: CLR проверяет, что значение k является ссылкой на упакованный тип int (или совместимый тип, такой как enum с базовым типом int), и копирует значение из этого поля в l.

Вы можете увидеть IL, сгенерированный для всего этого, скомпилировав код, а затем, конечно, используя ildasm или Reflector.

Эрик Липперт имеет сообщение в блоге обо всем этом, что может оказаться полезным.

...