Четверг, 13.05.2021, 12:15
Приветствую Вас Гость | RSS | PDA

Всё для студента информата

Полезная информация

Статьи IT

Всё для студента IT » Статьи » Программирование для Microsoft® .NET

Ссылочные и размерные типы

Благодаря упаковке/распаковке программист не замечает разделения на ссылочные и размерные типы. И все же иногда нужно знать, с какими типами вы работаете. Ведь тонкие различия между этими двумя разновидностями типов могут оказать на приложение такое воздействие, которого вы никак не ожидали.

Вот пример. В следующем коде определен простой ссылочный тип (класс) Point и объявлены две ссылки: p1 и p2. Ссылка p1 указывает на новый объект типа Point, а при инициации ссылки р2 она приравнивается p1. Поскольку р1 и р2 больше, чем просто замаскированные указатели, их приравнивание не приводит к созданию копии объекта Point — копируется только адрес, Поэтому изменение одного экземпляра Point отражается на обоих объектах:

class Point
{
public int x;
public Int y;
}
.
.
.
Point p1 = new Point ();
pl.x = 1;
pl.y = 2;
Point p2 = p1; // Копируется лежащий в основе указатель.
р2.х = 3;
р2.у = 4;
Console. WriteLine ("p1 = ({0}, {1})", pl.x, р1.у); // Выводится "(3, 4)",
Console. WriteLine ("p2 = ({0}, {1})", р2.х, р2.у); // Выводится "(3, 4)".

Следующий фрагмент идентичен предыдущему, однако теперь Point — размерный тип (struct). Но в силу того, что приравнивание одного размерного типа другому вызывает создание копии последнего, результат получается совершенно иным.

Изменение одного экземпляра Point больше не влияет на другой:

struct Point
{
public int x;
public int y;
}
.
.
.
Point p1 = new Point ();
pl.x = 1;
pl.y = 2;
Point p2 = p1; // В стеке создается новая копия объекта,
р2.х = 3;
р2.у = 4;
Console. WriteLine ("p1 = ({0}, {1»", pl.x, pl.y); // Выводится "(1. 2)".
Console. WriteLine ("p2 = ({0}, {1}}", р2.х. р2.у); // Выводится "(3, 4)".

Иногда различия между ссылочным и размерным типами еще коварней.

К примеру, если Point является размерным типом, этот код совершенно корректен:

Point p;
р.х = 3;
р. У = 4;

Но если Point относится к ссылочному типу, та же последовательность команд даже не пройдет компиляцию. Почему? Потому что оператор:

Point p;

для размерного типа объявляет экземпляр, а для ссылочного типа — только ссылку на этот ссылочный тип. Ссылка подобна указателю — она непригодна, пока не инициализирована, например так:

Point p = new Point ();

Программисты с опытом работы на C++ особенно подвержены этим ошибкам, потому что, увидев оператор, объявляющий ссылку, они считают, что создается объект в стеке.

FCL — смесь размерных и ссылочных типов. Ясно, что иногда важно знать, с каким типом вы имеете дело. Как выяснить, к ссылочному или к размерному типу относится конкретный FCL-тип? Просто. Если в документации сказано, что это класс (например, «String Class*), то он относится к ссылочному типу. Если же сказано, что это структура (например, «Date Time Structure*), то это размерный тип. Помните о различиях, и вам удастся избежать утомительных часов отладки в попытках выяснить, почему ваш замечательный код дает непредсказуемые результаты.

Похожие статьи:

Не нашли то, что Вам нужно?.. Найдите ответ на форуме!
Категория: Программирование для Microsoft® .NET | Добавил: Akron (14.02.2012)
Просмотров: 467 | Теги: .NET
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Сообщество
Помощь
Форма входа
Поиск

Студенческий помощник по информатике © 2021
При цитировании материалов данного сайта, обязательна ссылка на источник: ITstudents.ru



>