- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания C# 4.0: полное руководство - Герберт Шилдт
Шрифт:
Интервал:
Закладка:
public void NoChange(int i, int j) {
i = i + j;
j = -j;
}
}
class CallByValue {
static void Main() {
Test ob = new Test();
int a = 15, b = 20;
Console.WriteLine("а и b до вызова: " + a + " " + b) ;
ob.NoChange(a, b);
Console.WriteLine("а и b после вызова: " + a + " " + b) ;
}
}
Вот какой результат дает выполнение этой программы.
а и b до вызова: 15 20
а и b после вызова: 15 20
Как видите, операции, выполняемые в методе NoChange(), не оказывают никакого влияния на значения аргументов а и b, используемых для вызова данного метода. Это опять же объясняется тем, что параметрам i и j переданы копии значений аргументов а и b, а сами аргументы а и b совершенно не зависят от параметров i и j. В частности, присваивание параметру i нового значения не будет оказывать никакого влияния на аргумент а.
Дело несколько усложняется при передаче методу ссылки на объект. В этом случае сама ссылка по-прежнему передается по значению. Следовательно, создается копия ссылки, а изменения, вносимые в параметр, не оказывают никакого влияния на аргумент. (Так, если организовать ссылку параметра на новый объект, то это изменение не повлечет за собой никаких последствий для объекта, на который ссылается аргумент.) Но главное отличие вызова по ссылке заключается в том, что изменения, происходящие с объектом, на который ссылается параметр, окажут влияние на тот объект, на который ссылается аргумент. Попытаемся выяснить причины подобного влияния.
Напомним, что при создании переменной типа класса формируется только ссылка на объект. Поэтому при передаче этой ссылки методу принимающий ее параметр будет ссылаться на тот же самый объект, на который ссылается аргумент. Это означает, что и аргумент, и параметр ссылаются на один и тот же объект и что объекты, по существу, передаются методам по ссылке. Таким образом, объект в методе будет оказывать влияние на объект, используемый в качестве аргумента. Для примера рассмотрим следующую программу.
// Передача объектов по ссылке.
using System;
class Test {
public int a, b;
public Test(int i, int j) {
a = i; b = j;
}
/* Передать объект. Теперь переменные ob.a и ob.b из объекта, используемого в вызове метода, будут изменены. */
public void Change(Test ob) {
ob.a = ob.a + ob.b;
ob.b = -ob.b;
}
}
class CallByRef {
static void Main() {
Test ob = new Test(15, 20);
Console.WriteLine("ob.а и ob.b до вызова: " + ob.a + " " + ob.b);
ob.Change(ob);
Console.WriteLine("ob.а и ob.b после вызова: " + ob.a + " " + ob.b);
}
}
Выполнение этой программы дает следующий результат.
ob.a и ob.b до вызова: 15 20
ob.a и ob.b после вызова: 35 -20
Как видите, действия в методе Change() оказали в данном случае влияние на объект, использовавшийся в качестве аргумента.
Итак, подведем краткий итог. Когда объект передается методу по ссылке, сама ссылка передается по значению, а следовательно, создается копия этой ссылки. Но эта копия будет по-прежнему ссылаться на тот же самый объект, что и соответствующий аргумент. Это означает, что объекты передаются методам неявным образом по ссылке.
Использование модификаторов параметров ref и out
Как пояснялось выше, аргументы простых типов, например int или char, передаются методу по значению. Это означает, что изменения, вносимые в параметр, принимающий значение, не будут оказывать никакого влияния на аргумент, используемый для вызова. Но такое поведение можно изменить, используя ключевые слова ref и out для передачи значений обычных типов по ссылке. Это позволяет изменить в самом методе аргумент, указываемый при его вызове.
Прежде чем переходить к особенностям использования ключевых слов ref и out, полезно уяснить причины, по которым значение простого типа иногда требуется передавать по ссылке. В общем, для этого существуют две причины: разрешить методу изменить содержимое его аргументов или же возвратить несколько значений. Рассмотрим каждую из этих причин более подробно.
Нередко требуется, чтобы метод оперировал теми аргументами, которые ему передаются. Характерным тому примером служит метод Swap(), осуществляющий перестановку значений своих аргументов. Но поскольку аргументы простых типов передаются по значению, то, используя выбираемый в C# по умолчанию механизм вызова по значению для передачи аргумента параметру, невозможно написать метод, меняющий местами значения двух его аргументов, например типа int. Это затруднение разрешает модификатор ref.
Как вам должно быть уже известно, значение возвращается из метода вызывающей части программы с помощью оператора return. Но метод может одновременно возвратить лишь одно значение. А что, если из метода требуется возвратить два или более фрагментов информации, например, целую и дробную части числового значения с плавающей точкой? Такой метод можно написать, используя модификатор out.
Использование модификатора параметра refМодификатор параметра ref принудительно организует вызов по ссылке, а не по значению. Этот модификатор указывается как при объявлении, так и при вызове метода. Для начала рассмотрим простой пример. В приведенной ниже программе создается метод Sqr(), возвращающий вместо своего аргумента квадрат его целочисленного значения. Обратите особое внимание на применение и местоположение модификатора ref.
// Использовать модификатор ref для
// передачи значения обычного типа по ссылке.
using System;
class RefTest {
// Этот метод изменяет свой аргумент. Обратите
// внимание на применение модификатора ref.
public void Sqr(ref int i) {
i = i * i;
}
}
class RefDemo {
static void Main() {
RefTest ob = new RefTest();
int a = 10;
Console.WriteLine("а до вызрва: " + a);
ob.Sqr(ref a);
// обратите внимание на применение модификатора ref
Console.WriteLine("а после вызова: " + а);
}
}
Как видите, модификатор ref указывается перед объявлением параметра в самом методе и перед аргументом при вызове метода. Ниже приведен результат выполнения данной программы, который подтверждает, что значение аргумента а действительно было изменено с помощью метода Sqr().
а до вызова: 10
а после вызова: 100
Теперь, используя модификатор ref, можно написать метод, переставляющий местами значения двух своих аргументов простого типа. В качестве примера ниже приведена программа, в которой метод Swap() выполняет перестановку значений двух своих целочисленных аргументов, когда он вызывается.
// Поменять местами два значения.
using System;
class ValueSwap {
// Этот метод меняет местами свои аргументы,
public void Swap(ref int a, ref int b) {
int t;
t = a;
a = b;
b = t;
}
}
class ValueSwapDemo {
static void Main() {
ValueSwap ob = new ValueSwap();
int x=10, у = 20;
Console.WriteLine("x и у до вызова: " + x + " " + у);
ob.Swap(ref x, ref у);
Console.WriteLine("x и у после вызова: " + x + " " + у);
}