- •Классы и структуры
- •Функции-члены
- •Передача параметров в методы
- •Параметры ref
- •Параметры out
- •Свойства
- •Свойства, доступные только для чтения и только для записи
- •Модификаторы доступа для свойств
- •Автоматически реализуемые свойства
- •Замечание о встраивании
- •Индексаторы
- •Тип_элемента this[int индекс]
- •Листинг 1.
- •Листинг 2.
- •Листинг 3.
- •Листинг 4.
- •Конструкторы
- •Статические конструкторы
- •Вызов одних конструкторов из других
- •Поля readonly
- •Анонимные типы
- •Структуры
- •Структуры это типы значений
- •Структуры и наследование
- •Конструкторы структур
- •Частичные классы
- •Статические классы
- •Класс Object
- •Методы System.Object
- •Метод ToString()
- •Расширяющие методы
Параметры out
В С-подобных языках функции часто возвращают более одного значения. Это обеспечивается применением выходных параметров, за счет присваивания значений переменным, переданным в метод по ссылке. Часто первоначальное значение таких переменных не важно. Эти значения перезаписываются в функции, которая может даже не обращать внимания на то, что в них хранилось первоначально.
Было бы удобно использовать то же соглашение в С#. Однако в С# требуется, чтобы переменные были инициализированы каким-то начальным значением перед тем, как к ним будет выполнено обращение. Хотя можно инициализировать входные переменные какими-то бессмысленными значениями до передачи их в функцию, которая наполнит их осмысленными значениями, этот прием выглядит в лучшем случае излишним, а в худшем сбивающим с толку. Тем не менее, существует способ обойти требование компилятора С# относительно начальной инициализации переменных.
Это достигается ключевым словом out. Когда входной аргумент снабжен префиксом out, этому методу можно передать неинициализированную переменную. Переменная передается по ссылке, поэтому любые изменения, выполненные методом в переменной, сохраняются после того, как он вернет управление. Ключевое слово out также должно указываться при вызове метода так же, как при его определении:
static void SomeFunction (out int i)
{
i = 100;
}
public static int Main()
{
int i; // переменная i объявлена, но не инициализирована
SomeFunction(out i);
Console.WriteLine(i);
return 0;
}
Именованные аргументы
Обычно параметры должны передаваться в метод в том же порядке, в котором они определены. Именованные аргументы позволяют передавать параметры в любом порядке. То есть для приведенного ниже метода:
string FullName(string firstName, string lastName)
{
return firstName + " " + lastName;
}
возможны следующие вызовы, которые вернут одно и то же полное имя:
FullName("John", "Doe");
FullName(lastName: "Doe", firstName: "John");
Если метод имеет несколько параметров, в одном вызове можно смешивать позиционные и именованные параметры.
Необязательные аргументы
Параметры также могут быть необязательными. Для таких параметров должны определяться значения по умолчанию. Необязательные параметры должны располагаться последними в списке. Поэтому следующее объявление метода будет неправильным:
void TestMethod(int optionalNumber = 10, int notOptionalNumber)
{
System.Console.Write(optionalNumber + notOptionalNumber);
}
Чтобы этот метод работал, параметр optionalNumber должен быть определен последним.
Перегрузка методов
В С# поддерживается перегрузка методов может существовать несколько версий метода с разными сигнатурами (т.е. именем, количеством и/или типами параметров). Чтобы перегрузить методы, вы просто объявляете методы с одинаковыми именами, но разным с разным количеством или типами параметров:
class ResultDisplayer
{
void DisplayResult(string result)
{
// реализация
}
void DisplayResult(int result)
{
// реализация
}
}
Если вас не устраивают необязательные параметры, для достижения того же эффекта можно применить перегрузку методов:
class MyClass
{
int DoSomething(int x)
// нужен 2-й параметр со значением по умолчанию 10
{
DoSomething(х, 10);
}
int DoSomething(int x, int y)
{
// реализация
}
}
Как в любом другом языке, неправильная перегрузка методов чревата трудноуловимыми ошибками времени выполнения. В разделе 6.4 обсуждаются способы предотвращения этой проблемы при кодировании. А пока вы должны знать, что С# обеспечивает некоторую минимальную защиту относительно параметров перегруженных методов:
-
недостаточно, чтобы два метода отличались только типом возвращаемого значения;
-
недостаточно, чтобы два метода отличались только спецификацией параметров ref и out.