Книга: ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание

Передача ссылочных типов по значению

Передача ссылочных типов по значению

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

class Person {
 public string fullName;
 public byte age;
 public Person(string n, byte a) {
  fullName = n;
  age = a;
 }
 public Person() {}
 public void PrintInfo() { Console.WriteLine("{0}, {1} года (лет)", fullName, age); }
}

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

public static void SendAPersonByValue(Person p) {
 // Изменяет ли это возраст 'р'?
 p.age = 92;
 // Увидит ли вызывающая сторона такие изменения?
 p = new Person ("Никки", 192);
}

Обратите внимание на то, что метод SendAPersonByValue() пытается изменить получаемую ссылку Person на новый объект, а также изменить некоторые данные состояния. Давайте проверим работу этого метода, используя следующий метод Main().

static void Main(string[] args) {
 // Передача ссылочных типов по значению.
 Console.WriteLine("*** Передача объекта Person по значению ***");
 Person fred = new Persоn("Фред", 2);
 Console.WriteLine("Person до вызова по значению");
 fred.PrintInfo();
 SendAPersonByValue(fred);
 Console.WriteLine("Persоn после вызова по значению");
 fred.PrintInfо();
}

На рис. 3.15 показан соответствующий вывод.


Рис. 3.15. Передача ссылочных типов по значению блокирует соответствующую ссылку

Как видите, значение возраста (age) изменяется. Кажется, такое поведение при передаче параметра противоречит самому термину "по значению". Если вы способны изменить состояние получаемого объекта Person, что же все-таки копируется? Ответ здесь следующий: в объект вызывающей стороны копируется ссылка. Поэтому, поскольку метод SendAPersonByValue() и объект вызывающей стороны указывают на один и тот же объект, можно изменить состояние данных объекта. Что здесь невозможно, так это изменить саму ссылку так, чтобы она указывала на другой объект (это напоминает ситуацию с постоянными указателями в C++).

Оглавление книги


Генерация: 1.240. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз