Страница 93 из 502
<b>а до вызова: 10 </b>
<b>а после вызова: 100</b>
Теперь, используя модификатор ref, можно написать метод, переставляющий местами значения двух своих аргументов простого типа. В качестве примера ниже приведена программа, в которой метод Swap() выполняет перестановку значений двух своих целочисленных аргументов, когда он вызывается.
<b>// Поменять местами два значения.</b>
<b>using System;</b>
<b>class ValueSwap {</b>
<b> // Этот метод меняет местами свои аргументы, </b>
<b> public void Swap(ref int a, ref int b) { </b>
<b> int t; </b>
<b> t = a; </b>
<b> a = b;</b>
<b> b = t;</b>
<b> }</b>
<b>}</b>
<b>class ValueSwapDemo { </b>
<b> static void Main() {</b>
<b> ValueSwap ob = new ValueSwap();</b>
<b> int x=10, у = 20;</b>
<b> Console.WriteLine("x и у до вызова: " + x + " " + у); </b>
<b> ob.Swap(ref x, ref у);</b>
<b> Console.WriteLine("x и у после вызова: " + x + " " + у);</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этой программы.
<b>х и у до вызова: 10 20 </b>
<b>х и у после вызова: 20 10</b>
В отношении модификатора ref необходимо иметь в виду следующее. Аргументу, передаваемому по ссылке с помощью этого модификатора, должно быть присвоено значение до вызова метода. Дело в том, что в методе, получающем такой аргумент в качестве параметра, предполагается, что параметр ссылается на действительное значение. Следовательно, при использовании модификатора ref в методе нельзя задать первоначальное значение аргумента.
Иногда ссылочный параметр требуется использовать для получения значения из метода, а не для передачи ему значения. Допустим, что имеется метод, выполняющий некоторую функцию, например, открытие сетевого сокета и возврат кода успешного или неудачного завершения данной операции в качестве ссылочного параметра. В этом случае методу не передается никакой информации, но в то же время он должен возвратить определенную информацию. Главная трудность при этом состоит в том, что параметр типа ref должен быть инициализирован определенным значением до вызова метода. Следовательно, чтобы воспользоваться параметром типа ref, придется задать для аргумента фиктивное значение и тем самым преодолеть данное ограничение. Правда, в C# имеется более подходящий вариант выхода из подобного затруднения — воспользоваться модификатором параметра out.
Модификатор параметра out подобен модификатору ref, за одним исключением: он служит только для передачи значения за пределы метода. Поэтому переменной, используемой в качестве параметра out, не нужно (да и бесполезно) присваивать какое-то значение. Более того, в методе параметр out считается неинициализированным, т.е. предполагается, что у него отсутствует первоначальное значение. Это означает, что значение должно быть присвоено данному параметру в методе до его завершения. Следовательно, после вызова метода параметр out будет содержать некоторое значение.
Ниже приведен пример применения модификатора параметра out. В этом примере программы для разделения числа с плавающей точкой на целую и дробную части используется метод GetParts() из класса Decompose. Обратите внимание на то, как возвращается каждая часть исходного числа.
<b>// Использовать модификатор параметра out.</b>
<b>using System;</b>
<b>class Decompose {</b>
<b> /* Разделить числовое значение с плавающей точкой на целую и дробную части. */ </b>
<b> public int GetParts(double n, out double frac) { </b>
<b> int whole;</b>
<b> whole = (int) n;</b>
<b> frac = n - whole; // передать дробную часть числа через параметр frac </b>
<b> return whole; // возвратить целую часть числа</b>
<b> }</b>
<b>}</b>
<b>class UseOut {</b>
<b> static void Main() {</b>
<b> Decompose ob = new Decompose(); </b>
<b> int i; </b>
<b> double f;</b>
<b> i = ob.GetParts(10.125, out f) ;</b>
<b> Console.WriteLine("Целая часть числа равна " + i);</b>
<b> Console.WriteLine("Дробная часть числа равна " + f);</b>
<b> }</b>
<b>}</b>
Выполнение этой программы дает следующий результат.