@Madfisht3

Фрагмент книги C#. Как так может быть?

Типы значений, ссылочные типы и операция присваивания
Когда один тип значения присваивается другому, получается почленная копия по¬
лей данных. В случае простого типа данных, такого как System.Int32, единственным
копируемым членом является числовое значение. Однако в ситуации с типом Point ко¬
пироваться в новую переменную структуры будут значения X и Y. В целях иллюстрации
создадим новый проект консольного приложения по имени ValueAndReferenceTypes и
скопируем предыдущее определение Point в новое пространство имен. После этого до¬
бавим к типу Program следующий метод:
// Присваивание двух внутренних типов значений в результате
/ / дает две независимых переменных в стеке.
static void ValueTypeAssignment()
{
Console.WriteLine("Assigning value types\n");
Point pl = new Point(10, 10);
Point p2 = pl;
// Вывести обе переменных Point.
pl.Display();
p2.Display();
// Изменить pl.X и вывести снова. Значение p2.X не изменилось.
pl.X = 100;
Console.WriteLine("\n=> Changed pl.X\n");
pl.Display();
p2.Display();
}
Здесь сначала создается переменная типа Point (pl), которая затем присваивается
другой переменной типа Point (p2). Поскольку Point относится к типу значения, в сте¬
ке размещаются две копии MyPoint, каждой из которых можно манипулировать незави¬
симо. Поэтому при изменении значения pl.X значение p2.X остается незатронутым:
Assigning value types
X = 10, Y = 10
X = 10, Y = 10
=> Changed pl. 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 pl = new PointRef(10, 10);
PointRef p2 = pl;
// Вывести обе переменных PointRef.
pl.Display();
p2.Display();
// Изменить pl.X и вывести снова.
pl.X = 100;
Console.WriteLine("\n=> Changed pl.X\n");
pl.Display();
p2.Display();
}
В этом случае получаются две ссылки, указывающие на один и тот же объект в уп¬
равляемой куче. Таким образом, при изменении значения X с использованием ссылки
pl изменится также и значение p2 . X. Вызов этого нового метода в Main () дает следу¬
ющий вывод:
Assigning reference types
X = 10, Y = 10
X = 10, Y = 10
=> Changed pl.X
X = 100, Y = 10
X = 100, Y = 10

Я что-то не понимаю. Где здесь ссылки? Во втором случае то же самое, что и в первом. Почленное копирование. Каждое поле имеет отдельный адрес.
  • Вопрос задан
  • 420 просмотров
Пригласить эксперта
Ответы на вопрос 1
petermzg
@petermzg
Самый лучший программист
Во втором случае нет почленного копирования. pl и pl2 указывают на один адрес памяти.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы