- •А. А. Волосевич
- •Содержание
- •1. Общая характеристика платформы .Net
- •1.1. Инфраструктура платформы .Net
- •1.2. Версии платформы .Net
- •2. Общие концепции синтаксиса языка c#
- •3. Система типов clr и языка c#
- •4. Идентификаторы, ключевые слова и литералы
- •5. Выражения и операции
- •1. Первичные операции
- •2. Унарные операции
- •6. Операторы
- •6.1. Операторы объявления
- •6.2. Операторы выражений
- •6.3. Операторы перехода
- •6.4. Операторы выбора
- •6.5. Операторы циклов
- •6.6. Прочие операторы
- •7. Начальные сведения о массивах
- •8. Классы
- •8.1. Допустимые элементы класса
- •8.2. Модификаторы доступа для элементов и типов
- •8.3. Разделяемые классы
- •8.4. Использование класса
- •9. Методы
- •9.1. Описание метода
- •9.2. Вызов метода
- •9.3. Разделяемые методы
- •10. Свойства и индексаторы
- •11. Статические элементы и методы расширения
- •11.1. Статические элементы
- •11.2. Статические классы
- •11.3. Методы расширения
- •12. Конструкторы и инициализация объектов
- •13. Наследование классов
- •14. КлассSystem.Objectи иерархия типов
- •15. Структуры
- •16. Перечисления
- •17. Интерфейсы
- •18. Универсальные шаблоны
- •18.1. Универсальные классы и структуры
- •18.2. Ограничения на параметры универсальных типов
- •18.3. Ковариантность и контравариантность
- •18.4. Универсальные методы
- •19. Использование универсальных шаблонов
- •19.1. Кортежи
- •19.2. Типы, допускающие значение null
- •19.3. Прочие примеры универсальных шаблонов
- •20. Делегаты
- •21. Анонимные методы и лямбда-выражения
- •22. События
- •23. Перегрузка операций
- •24. Анонимные типы
- •25. Пространства имён
- •26. Генерация и обработка исключительных ситуаций
- •27. Директивы препроцессора
- •28. Документирование исходного кода
- •Литература
9.2. Вызов метода
При вызове метода на место формальных параметров помещаются фактические аргументы. При этом вначале производится вычисление всех аргументов (если они заданы выражениями). Вычисление аргументов всегда происходит последовательно, слева направо. Соответствие между параметром и аргументом устанавливается либо по позиции, либо используя синтаксисименованных аргументов:
имя-формального-параметра: выражение-для-аргумента
Рассмотрим примеры вызова метода Add(), содержащего три параметра:
intAdd(intx,inty = 3,intz = 5)
{
return x + y + z;
}
int res_1 = Add(10, 20, 30); // передача по позиции
int res_2 = Add(x:10, z:20, y:30); // именованные параметры
int res_3 = Add(10, z:20, y:30); // комбинирование двух способов
Использование именованных аргументов зачастую необходимо, если метод содержит опциональные параметры:
int res_4 = Add(10, z:20);
Метод с параметром-списком можно вызвать несколькими способами. Можно указать в качестве аргумента массив или передать методу произвольное (даже нулевое) количество аргументов соответствующего типа. Во втором случае для хранения аргументов будет создан временный массив (это немного снижает производительность):
// передаём два аргумента
PrintList(10, 20);
// теперь передаём четыре аргумента
PrintList(1, 2, 3, 4);
// создаём и передаём массив целых чисел
PrintList(new[] {10, 20, 30, 40});
// можем вообще ничего не передавать
PrintList();
Если при описании параметра использовались модификаторы refилиout, то они должны быть указаны и при вызове. Кроме этого, фактические аргументы с такими модификаторами должны быть представлены переменными, а не литералами или выражениями. В случае параметров-значений тип аргумента должен совпадать или неявно приводится к типу формального параметра. При согласовании типов в случае возникновения двусмысленности делается выбор числового типа из той же группы знаковости. Например, пусть имеются перегруженные методыM(uint x)иM(int x), а переменнаяyимеет типushort. Тогда вызовM(y)означает вызов версии с формальным параметром типаuint. Дляref- иout-параметров требуется абсолютное совпадение типов.
9.3. Разделяемые методы
Разделяемые классы и структуры могут содержать разделяемые методы. Разделяемый метод состоит из двух частей: заголовка и реализации. Обычно эти части размещаются в различных частях разделяемого типа. Выглядит это следующим образом:
publicpartialclassStudent
{
partialvoidM(intx);
}
publicpartialclassStudent
{
partialvoidM(intx)
{
Console.WriteLine("M body");
}
}
Разделяемые методы подчиняются следующим правилам:
– объявление метода начинается с модификатора partial;
– метод обязан возвращать значение void;
– метод может иметь параметры, но out-параметры запрещены;
– метод неявно объявляется как private(поэтому он не может быть виртуальным);
– разделяемые методы могут быть статическими или универсальными;
– вызов разделяемого метода нельзя инкапсулировать в делегат.
Отметим ещё одну особенность разделяемого метода: его реализация может быть опущена. В этом случае компилятор даже не генерирует код вызовов разделяемого метода.