- •Программа курса
- •Ооп. Основные понятия
- •Конструкторы, деструкторы и др. Работа с объектами в .Net
- •Ссылочные типы и Типы значения. Передача параметров в .Net
- •Принципы ооп
- •Инкапсуляция
- •Наследование
- •Полиморфизм
- •Важные классы (типы данных)
- •Обобщенные контейнеры
- •Статические методы и свойства
- •Обработка исключений
- •Интерфейсы и слабая связь между классами
- •Рефлексия и создание объектов из внешних модулей по имени класса
Ссылочные типы и Типы значения. Передача параметров в .Net
(Ссылочные типы, типы значения, передача параметров по ссылке и по значению)
Все, что было сказано выше об объектах и ссылках – основной способ работы с данными в .Net. Но все же есть одна существенная особенность. Все выше сказанное применимо ко всем объектам всех классов. Они называются ссылочные типы или Reference types. Но в C# есть очень часто встречаемые типы данных, с которыми программист работает непосредственно, т.е. не через ссылки, а прямо со значениями. Такие типы данных называются Типы значений или Value types. К ним относятся все числовые типы, тип char, представляющий единичный символ, тип логических величин bool, перечисления и структуры. С последними представителями типов значений можно более детально ознакомиться по справочной документации по языку C#.
Типы значения не имеют ссылок, а переменные этих типов прямо представляют значения этих переменных. Так в объявлении int x = 3, x – не ссылка, а целочисленная переменная, содержащая значение 3. Присваивание одной переменной другой переменной не увеличивает количество ссылок на исходную переменную, а копирует значение из одной переменной в другую.
Соответственно, если такая переменная уходит из области существования, то ее значение сразу же исчезает, а не освобождается сборщиком мусора.
Такое разделение сделано с целью повышения эффективности возникающего в результате компиляции программного кода.
Наиболее ярко различия в двух категориях величин проявляется при передаче параметров в методы. Рассмотрим алгоритм обмена 2-х переменных своими значениями. На английском языке такая операция называется swap (своп).
public static Swap(int a, int b)
{
int c = a;
a = b;
b = c;
}
Фрагмент 5. Попытка метода для обмена 2-х целочисленных переменных значениями.
С алгоритмической точки зрения этот метод правильный и в пределах него a и b обменяются значениями. Но при вызове для внешних величин он не произведет никакого действия, т.е. Swap(x, y); никак не повлияет на значения переменных x и y.
Дело в том, что в C# принято соглашение, что передача параметров выполняется ‘по значению’. Т.е. передаются не сами параметры, а лишь их значения. В нашем случае, при вызове Swap были созданы 2 вспомогательные переменные, которые видны внутри метода как a и b и все действия были выполнены над ними. На внешние переменные – фактические параметры вызова, это не произвело никакого действия.
Что бы получить ожидаемый эффект, нужно было параметры Swap объявить как ‘передаваемые по ссылке’. Синтаксически это делается так:
public static Swap(ref int a, ref int b)
{
int c = a;
a = b;
b = c;
}
Фрагмент 6. Метод для обмена 2-х целочисленных переменных значениями.
Вызов такого метода выглядит как Swap(ref x, ref y). Вот теперь, параметры a и b – это, фактически, вторые имена для фактических параметров x и y, а все действия выполняются непосредственно над переменными x и y. Такое обращение приведет к тому, что фактические параметры вызова обменяются своими значениями.
Что если вместо Типа значения создать аналогичный метод для каких-нибудь объектов, т.е. Ссылочного типа? Окажется, что теперь для фрагмента кода 5 копироваться будут ссылки, и снова, никакого влияния на внешние величины (фактические параметры) метод никакого влияния не окажет. Метод же приведенный во фрагменте 6 сработает. С этой точки зрения ссылочные типы и типы значения не отличаются.
Различие между ссылочными типами и типами значений проявятся, если в теле метода изменять свойства объектов (параметров). Хотя для ссылочного типа мы работаем с копией ссылки, но сам объект является исходным и все действия осуществляются именно над ним.
Упражнения для подготовки к экзамену.
Какие 2 способа передачи параметров в методы рассмотрены в этом разделе? Чем они отличаются?
В чем различие между типами значениями и ссылочными типами в .Net?
Как указать компилятору, что параметры нужно передавать по ссылке?