Выбрать главу

// Выходные параметры задаются членом.

public static void Add(int x, int y, out int ans) {

 ans = x + y;

}

При вызове метода с выходными параметрами тоже требуется указать модификатор out. Локальным переменным, используемым в качестве выходного параметра, не требуется присваивать значения до их использования (эти значения после вызова все равно будут потеряны), Например:

static void Main(string[] args) {

 // Нет необходимости задавать значения

 // локальным выходным переменным.

 int ans;

 Add(90, 90, out ans);

 Console.WriteLine("90 + 90 = {0} ", ans);

}

Этот пример предлагается здесь только для иллюстрации: нет никакой необходимости возвращать значение суммы с помощью выходного параметра. Но сам модификатор out играет очень важную роль: он позволяет вызывающей стороне получить множество возвращаемых значений от одного вызова метода.

// Возвращение множества выходных параметров.

public static void FillTheseVals(out int a, out string b, out bool c) {

 а = 9;

 b = "Радуйтесь своей строке.";

 с = true;

}

Вызывающая сторона может вызвать этот метод следующим образом.

static void Main(string[] args) {

 int i; string str; bool b;

 FillTheseVals(out i, out str, out b);

 Console.WriteLine("Int равно: {0}", i);

 Console.WriteLine("String равно: (0}", str);

 Console.WriteLine("Boolean равно: {0}", b);

}

Модификатор ref

Теперь рассмотрим, использование в C# модификатора ref (от reference – ссылочный). Ссылочные параметры нужны тогда, когда требуется позволить методу изменять данные, объявленные в контексте вызова (например, в функциях сортировки или обмена данными). Обратите внимание на различие между выходными и ссылочными параметрами.

• Выходные параметры не требуется инициализировать перед передачей их методу. Причина в том, что сам метод должен присвоить значения выходным параметрам.

• Ссылочные параметры необходимо инициализировать до того, как они будут переданы методу. Причина в том, что передается ссылка на существующую переменную. Если не присвоить переменной начальное значение, это будет означать использование неинициализированной переменной.

Давайте продемонстрируем использование ключевого слова ref с помощью метода, в котором осуществляется обмен значениями двух строк.

// Ссылочные параметры.

public static void SwapStrings(ref string s1, ref string s2) {

 string tempStr = s1;

 s1 = s2;

 s2 = tempStr;

}

Этот метод можно вызвать так.

static void Main(string[] args) {

 string s = "Первая строка";

 string s2 = "Вторая строка";

 Console.WriteLine("До: {0}, {1} ", s, s2);

 SwapStrings(ref s, ref s2);

 Console.WriteLine("После: {0}, {1} ", s, s2);

}

Здесь вызывающая сторона присваивает начальное значение локальным строковым данным (s и s2). По завершении вызова SwapStrings() строка s содержит значение "Вторая строка", a s2 – значение "Первая строка".

Модификатор params

Нам осталось рассмотреть модификатор params, позволяющий создавать методы, которым можно направить множество однотипных аргументов в виде одного параметра. Чтобы прояснить суть дела, рассмотрим метод, возвращающий среднее для любого числа значений,

// Возвращение среднего для 'некоторого числа' значений.

static double CalculateAverage(params double[] values) {

 double sum = 0;

 for (int i = 0; i ‹ values.Length; i++) sum += values[i];

 return (sum / values.Length);

}

Этот метод принимает массив параметров, состоящий из значений с двойной точностью. Метод фактически говорит следующее: "Дайте мне любой набор значений с двойной точностью, и я вычислю для них среднюю величину". Зная это, вы можете вызвать CalculateAverage() одним из следующих способов (если не использовать модификатор params в определении CalculateAverage(), то первый из указанных ниже вариантов вызова этого метода должен привести к ошибке компиляции).

static void Main(string[] args) {

 // Передача в виде списка значений, разделенных запятыми,.…

 double average;

 average = CalculateAverage(4.0, 3.2, 5.7);

 Console.WriteLine("Среднее 4.0, 3.2, 5.7 равно: {0}", average);

 //… или передача в виде массива значений.

 double[] data = {4.0, 3.2, 5.7};

 average = CalculateAverage(data);

 Console.WriteLine ("Среднее равно: {0}", average);

 Console.ReadLine();

}

Это завершает наше вводное обсуждение модификаторов параметров. Мы снова обратимся к этой теме немного позже (в этой же главе), когда будем обсуждать различия между типами значений и ссылочными типами. А пока что давайте рассмотрим итерационные и условные конструкции языка программирования C#.