Чтение онлайн

на главную - закладки

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

// Присваивание двух внутренних типов значений дает

// в результате две независимые переменные в стеке.

static void ValueTypeAssignment

{

Console.WriteLine("Assigning value types\n");

Point p1 = new Point(10, 10);

Point p2 = p1;

// Вывести значения обеих переменных Point.

p1.Display;

p2.Display;

// Изменить pl.X и снова вывести значения переменных.

//
Значение р2.Х не изменилось.

p1.X = 100;

Console.WriteLine("\n=> Changed p1.X\n");

p1.Display;

p2.Display;

}

Здесь создается переменная типа

Point(p1)
, которая присваивается другой переменной типа
Point(р2)
. Поскольку
Point
— тип значения, в стеке находятся две копии
Point
, каждой из которых можно манипулировать независимым образом. Поэтому при изменении значения
p1.X
значение
р2.X
остается незатронутым:

Assigning value types

X = 10, Y = 10

X = 10, Y = 10

=> Changed p1.X

X = 100, Y = 10

X = 10, Y = 10

По контрасту с типами значений, когда операция присваивания применяется к переменным ссылочных типов (т.е. экземплярам всех классов), происходит перенаправление на то, на что ссылочная переменная указывает в памяти. В целях иллюстрации создайте новый класс по имени

PointRef
с теми же членами, что и у структуры
Point
, но только переименуйте конструктор в соответствии с именем данного класса:

// Классы всегда являются ссылочными типами.

class PointRef

{

// Те же самые члены, что и в структуре Point...

// Не забудьте изменить имя конструктора на PointRef!

public PointRef(int xPos, int yPos)

{

X = xPos;

Y = yPos;

}

}

Задействуйте готовый тип

PointRef
в следующем новом методе. Обратите внимание, что помимо использования класса
PointRef
вместо структуры
Point
код идентичен коду метода
ValueTypeAssignment
:

static void ReferenceTypeAssignment

{

Console.WriteLine("Assigning reference types\n");

PointRef p1 = new PointRef(10, 10);

PointRef p2 = p1;

// Вывести значения обеих переменных PointRef.

p1.Display;

p2.Display;

// Изменить pl.X и снова вывести значения.

p1.X = 100;

Console.WriteLine("\n=> Changed p1.X\n");

p1.Display;

p2.Display;

}

В рассматриваемом

случае есть две ссылки, указывающие на тот же самый объект в управляемой куче. Таким образом, когда значение
X
изменяется с использованием ссылки
p1
, изменится также и значение
р2.X
. Вот вывод, получаемый в результате вызова этого нового метода:

Assigning reference types

X = 10, Y = 10

X = 10, Y = 10

=> Changed p1.X

X = 100, Y = 10

X = 100, Y = 10

Использование типов значений, содержащих ссылочные типы

Теперь, когда вы лучше понимаете базовые отличия между типами значений и ссылочными типами, давайте обратимся к более сложному примеру. Предположим, что имеется следующий ссылочный тип (класс), который поддерживает информационную строку (

InfoString
), устанавливаемую с применением специального конструктора:

class ShapeInfo

{

public string InfoString;

public ShapeInfo(string info)

{

InfoString = info;

}

}

Далее представим, что переменная типа

ShapeInfo
должна содержаться внутри типа значения по имени
Rectangle
. Кроме того, в типе
Rectangle
предусмотрен специальный конструктор, который позволяет вызывающему коду указывать значение для внутренней переменной-члена типа
ShapeInfo
. Вот полное определение типа
Rectangle
:

struct Rectangle

{

// Структура Rectangle содержит член ссылочного типа.

public ShapeInfo RectInfo;

public int RectTop, RectLeft, RectBottom, RectRight;

public Rectangle(string info, int top, int left, int bottom, int right)

{

RectInfo = new ShapeInfo(info);

RectTop = top; RectBottom = bottom;

RectLeft = left; RectRight = right;

}

public void Display

{

Console.WriteLine("String = {0}, Top = {1}, Bottom = {2}, " +

"Left = {3}, Right = {4}",

RectInfo.InfoString, RectTop, RectBottom, RectLeft, RectRight);

}

}

Здесь ссылочный тип содержится внутри типа значения. Возникает важный вопрос: что произойдет в результате присваивания одной переменной типа

Rectangle
другой переменной того же типа? Учитывая то, что уже известно о типах значений, можно корректно предположить, что целочисленные данные (которые на самом деле являются структурой —
System.Int32
)должны быть независимой сущностью для каждой переменной
Rectangle
. Но что можно сказать о внутреннем ссылочном типе? Будет ли полностью скопировано состояние этого объекта или же только ссылка на него? Чтобы получить ответ, определите следующий метод и вызовите его:

Поделиться:
Популярные книги

Свадьба по приказу, или Моя непокорная княжна

Чернованова Валерия Михайловна
Любовные романы:
любовно-фантастические романы
5.57
рейтинг книги
Свадьба по приказу, или Моя непокорная княжна

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Отец моего жениха

Салах Алайна
Любовные романы:
современные любовные романы
7.79
рейтинг книги
Отец моего жениха

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Бастард Императора. Том 7

Орлов Андрей Юрьевич
7. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 7

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Таня Гроттер и магический контрабас

Емец Дмитрий Александрович
1. Таня Гроттер
Фантастика:
фэнтези
8.52
рейтинг книги
Таня Гроттер и магический контрабас

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Кодекс Крови. Книга ХI

Борзых М.
11. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХI

Третий

INDIGO
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9

Потусторонний. Книга 1

Погуляй Юрий Александрович
1. Господин Артемьев
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Потусторонний. Книга 1