- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
}
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++).
Передача ссылочных типов по ссылке
Теперь предположим, что у нас есть метод SendAPersonByReference(), который передает ссылочный тип по ссылке (обратите внимание на то, что здесь присутствует модификатор параметра ref).
public static void SendAPersonByReference(ref Person p) {
// Изменение некоторых данных 'р'.
p.age = 122;
// Теперь 'р' указывает на новый объект в динамической памяти!
р = new Person("Никки", 222);
}
Как вы можете догадаться сами, это обеспечивает вызывающей стороне полную гибкость в управлении входными параметрами. Вызывающая сторона не только может изменить состояние объекта, но и переопределить ссылку так, чтобы она указывала на новый тип Person. Рассмотрите следующий вариант.
static void Main(string[] args) {
// Передача ссылочных типов по ссылке.
Console.WriteLine("n*** Передача объекта Person по ссылке ***");
Person mel = new Person("Мэл", 23);
Console.WriteLine("Person до вызова по ссылке:");
mel.PrintInfo();
SendAPersonByReference(ref mel);
Console.WriteLine("Person после вызова по ссылке:");
mel.PrintInfо();
}
Из рис. 3.16 видно, что тип с именем Мэл возвращается после вызова как тип с именем Никки.
Рис. 3.16. Передача ссылочных типов по ссылке позволяет перенаправить ссылку
Золотым правилом при передаче ссылочных типов по ссылке является следующее.
• Если ссылочный тип передается по ссылке, то вызывающая сторона может изменить не только состояние данных соответствующего объекта, но сам объект ссылки.
Исходный код. Проект RefTypeValTypeParams размещен в подкаталоге, соответствующем главе 3.
Типы, характеризуемые значениями, и ссылочные типы: заключительные замечания
Чтобы завершить обсуждение данной темы, изучите информацию табл. 3.8, в которой приводится краткая сводка основных отличий между типами, характеризуемыми значением, и ссылочными типами.
Таблица 3.8. Сравнение типов, характеризуемых значением, и ссылочных типов
Вопрос Тип, характеризуемый значением Ссылочный тип Где размещается тип? В стеке В управляемой динамический памяти Как представляется переменная? В виде локальной копии В виде ссылки на место в памяти, занятое соответствующим экземпляром Что является базовым типом? Оказывается производным от System.ValueType Может получаться из любого типа, (кроме System.ValueType), не являющегося изолированным (подробности в главе 4) Может ли тип быть базовым для других типов? Нет. Типы, характеризуемые значениями, всегда изолированы и не могут быть расширены Да. Если тип не изолирован, он может быть базовым для других типов Каким является поведение, принятое по умолчанию при передаче параметров? Переменные передаются по значению (т.е. вызванной функции передается копия переменной) Переменные передаются по ссылке (например, в вызванную функцию передается адрес переменной) Может ли тип переопределить System.Object.Finalize()? Нет. Типы, характеризуемые значениями, никогда не размещаются в динамической памяти и поэтому не требуют финализации Да, неявно (подробности в главе 4) Можно ли определить конструкторы для этого типа? Да, но конструктор, заданный по умолчанию, является зарезервированным (т.е., другие конструкторы обязательно должны иметь аргументы) Безусловно! Когда переменные данного типа прекращают свое существование? Когда они оказываются вне контекста определения Когда для управляемой динамической памяти выполняется сборка мусораНесмотря на указанные отличия, и типы, характеризуемые значением, и ссылочные типы могут реализовывать интерфейсы и поддерживать любое число полей, методов, перегруженных операций, констант, свойств и событий.
Операции создания объектного образа и восстановления из объектного образа
Ввиду того, что в .NET определяются две главные категории типов (характеризуемые значением или ссылкой), может понадобиться представление переменной одной категории в виде переменной другой категории. В C# предлагается очень простой механизм, называемый операцией создания объектного образа (boxing), позволяющий превратить тип, характеризуемый значением, в ссылочный тип. Предположим, что вы создали переменную типа short.
// Создание значения типа short.
short s =25;
Если в приложении потребуется конвертировать этот тип значения в ссылочный тип, вы должны "упаковать" это значение так, как показано ниже.
// "Упаковка" значения в объектную ссылку.
object objShort = s;
Операцию создания объектного образа можно формально определить, как процесс явного преобразования типа, характеризуемого значением, в соответствующий ссылочный тип с помощью сохранения переменной в System.Object. Когда значение преобразуется в объектный тип, среда CLR размещает новый объект в динамической памяти и копирует значение соответствующего типа (в данном случае это значение 25) в созданный экземпляр. Вам возвращается ссылка на новый размещенный в памяти объект. При использований такого подхода у разработчика .NET не возникает необходимости использовать интерфейсные классы, чтобы временно обращаться с данными стека как с объектами, размещенными в динамической памяти.
Обратная операция тоже предусмотрена, и называется она восстановлением из объектного образа (unboxing). Восстановление из объектного образа является процессом обратного преобразования значения, содержащегося в объектной ссылке, в значение соответствующего типа, размещаемое в стеке. Операция восстановления из объектного образа начинается с проверки того, что тип данных, в который выполняется восстановление, эквивалентен типу, который был приведён к объекту. Если это так, то выполняется обратное копирование соответствующего значения в локальную переменную в стеке. Например, следующая операция восстановления из объектного образа будет выполнена успешно, поскольку соответствующий тип objShort действительно имеет тип short (операцию преобразования типов в C# мы рассмотрим подробно в следующей главе, а пока что не слишком беспокойтесь о деталях).