|
Семантика присваивания. Преобразования между ссылочными и значимыми типамиРассматривая семантику присваивания и передачи аргументов, мы обошли молчанием один важный вопрос. Будем называть целью левую часть оператора присваивания, а также формальный аргумент при передаче аргументов в процедуру или функцию. Будем называть источником правую часть оператора присваивания, а также фактический аргумент при передаче аргументов в процедуру или функцию. Поскольку источник и цель могут быть как значимого, так и ссылочного типа, то возможны четыре различные комбинации. Рассмотрим их подробнее.
Операции "упаковать" и "распаковать" (boxing и unboxing). Примеры В нашем следующем примере демонстрируется применение обеих операций - упаковки и распаковки. Поскольку формальный аргумент процедуры Back принадлежит классу Object, то при передаче фактического аргумента значимого типа происходит упаковка значения в объект. Этот объект и возвращается процедурой. Его динамический тип определяется тем объектом памяти, на который указывает ссылка. Когда возвращаемый результат присваивается переменной значимого типа, то, несмотря на совпадение типа переменной с динамическим типом объекта, необходимо выполнить распаковку, "содрать" объектную упаковку и вернуть непосредственное значение. Вот как выглядит процедура Back и тестирующая ее процедура BackTest из класса Testing: /// <summary>/// Возвращает переданный ему аргумент./// Фактический аргумент может иметь произвольный тип./// Возвращается всегда объект класса object./// Клиент, вызывающий метод, должен при необходимости /// задать явное преобразование получаемого результата/// </summary>/// <param name="any"> Допустим любой аргумент</param>/// <returns></returns>object Back(object any){ return(any);}/// <summary>/// Неявное преобразование аргумента в тип object/// Явное приведение типа результата./// </summary>public void BackTest(){ ux = (uint)Back(ux); WhoIsWho("ux",ux); s1 = (string)Back(s); WhoIsWho("s1",s1); x =(int)(uint)Back(ux); WhoIsWho("x",x); y = (float)(double)Back(11 + 5.55 + 5.5f); WhoIsWho("y",y);}Обратите внимание, что если значимый тип в левой части оператора присваивания не совпадает с динамическим типом объекта, то могут потребоваться две операции приведения. Вначале нужно распаковать значение, а затем привести его к нужному типу, что и происходит в двух последних операторах присваивания. Приведу результаты вывода на консоль, полученные при вызове процедуры BackTest в процедуре Main.
Две двойственные операции "упаковать" и "распаковать" позволяют, в зависимости от контекста, рассматривать значимые типы как ссылочные, переменные как объекты, и наоборот. истематическому изучению возможностей языка. ![]() ![]() Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор... ![]() Живите по правилу: МАЛО ЛИ ЧТО НА СВЕТЕ СУЩЕСТВУЕТ? Я неслучайно подчеркиваю, что место в голове ограничено, а информации вокруг много, и что ваше право... ![]() ЧТО ТАКОЕ УВЕРЕННОЕ ПОВЕДЕНИЕ В МЕЖЛИЧНОСТНЫХ ОТНОШЕНИЯХ? Исторически существует три основных модели различий, существующих между... ![]() Что будет с Землей, если ось ее сместится на 6666 км? Что будет с Землей? - задался я вопросом... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|