Г. Шилдт - Полный справочник по C# (1160789), страница 38
Текст из файла (страница 38)
наименьший общий множитель, a gcd — этоаббревиатура от greatest common denominator, т.е. наибольший общий множитель.) Воткаковы результаты выполнения этой программы:Lcd для чисел 231 и 105 равен 3Gcd для чисел 231 и 105 равен 21Для чисел 35 и 51 общего множителя нет.IИспользование модификаторов r e f и out для ссылочныхпараметровИспользование модификаторов r e f и out не ограничивается параметрами типазначений.
Их также можно применить к ссылочным параметрам, т.е. параметрам,обеспечивающим передачу объектов. Если параметр ссылочного типа модифицируетсяодним из модификаторов ref и out, то по сути реализуется передача ссылки поссылке. Это позволяет методу изменять объект, на который указывает ссылкапараметр. Рассмотрим программу, в которой используются ссылочные ref-параметрыдля обмена объектами, на которые указывают две ссылки.Глава 8.
Подробнее о методах и классах195// Обмен двух ссылок,using System;class RefSwap {int a, b;public RefSwap(int i, int j) {a = i;b = j;public void show() {Console.WriteLine("a: {0}, b: {1}", a, b)// Этот метод теперь изменяет свои аргументы,public void swap(ref RefSwap obi, ref RefSwap ob2) {RefSwap t;t = obi;obi = ob2;ob2 = t;class RefSwapDemo {public static void Main() {RefSwap x = new RefSwap(1, 2 ) ;RefSwap у = new RefSwap(3, 4 ) ;Console.Write("x перед вызовом: ") ;x.show();Console.Write("у перед вызовом: " ) ;у.show();Console.WriteLine();// Обмениваем объекты, на которые ссылаются х и у.х.swap(ref х, ref у ) ;Console.Write("х после вызова: " ) ;х.show();Console.Write("у после вызова: " ) ;у.show();При выполнении этой программы получаем такие результаты:х перед вызовом: а: 1, Ь: 2у перед вызовом: а: 3, Ь: 4х после вызова: а: 3, Ь: 4у после вызова: а: 1, Ь: 2196Часть I.
Язык С #В этом примере метод swap () меняет местами объекты, на которые ссылаются дваего аргумента. До вызова метода swap () переменная х ссылается на объект, которыйсодержит значения 1 и 2, а переменная у ссылается на объект, который содержит значения 3 и 4. После обращения к методу swap () переменная х ссылается на объект,который содержит значения 3 и 4, а переменная у ссылается на объект, который содержит значения 1 и 2. Если бы здесь не были использованы ref-параметры, то обмен внутри метода swapO никак не повлиял бы на "среду" за его пределами. Этоможно доказать, убрав модификаторы из метода swap ().Использование переменного количествааргументовПри создании метода обычно заранее известно количество аргументов, которыебудут ему передаваться.
Но иногда необходимо, чтобы метод принимал произвольноечисло аргументов. Рассмотрим, например, метод, который находит минимальное значение в наборе чисел. Такому методу может быть передано два, три или четыре значения. В любом случае метод должен возвращать наименьшее значение. Такой методневозможно создать при использовании обычных параметров. Здесь необходимо применить специальный тип параметра, который заменяет собой произвольное количество параметров.
Это реализуется с помощью модификатора params.Модификатор params используется для объявления параметра-массива, которыйсможет получить некоторое количество аргументов (в том числе и нулевое). Количество элементов в массиве будет равно числу аргументов, переданных методу.Рассмотрим пример, в котором модификатор params используется для созданияметода minVal (), возвращающего минимальное значение из набора.// Демонстрация использования модификатора params.using System;class Min {public int minVal(params int[] nums) {int m;if(nums.Length = = 0 ) {Console.WriteLine("Ошибка:r e t u r n 0;нет аргументов.");m = nums [0];for (int i=l; i < nums.Length; i++)if(nums[i] < m) m = nums[i];return m;class ParamsDemo {public static void Main() {Min ob = new Min();int min;int a = 10, b = 20;Глава 8. Подробнее о методах и классах197// Вызываем метод с двумя значениями.min = ob.minVal(a, b ) ;Console.WriteLine("Минимум равен " + min);// call with 3 valuesmin = ob.minVal(a, b, - 1 ) ;Console.WriteLine("Минимум равен " + min);// Вызываем метод с пятью значениями,min = ob.minVal(18, 23, 3, 14, 25);Console.WriteLine("Минимум равен " + min);// Этот метод можно также вызвать с int-массивом.int[] args = { 45, 67, 34, 9, 112, 8 };min = ob.minVal(args);Console.WriteLine("Минимум равен " + min);Вот результатыМинимум равенМинимум равенМинимум равенМинимум равенвыполнения этой программы:10-138При каждом вызове метода minVal () аргументы передаются ему через массивnums.
Длина этого массива равна количеству элементов. Поэтому метод minVal Оможно использовать для определения минимального из любого числа элементов.Несмотря на то что params-параметру можно передать любое количество аргументов, все они должны иметь тип, совместимый с типом массива, заданным этим параметром.
Например, такой вызов метода minVal ()1 min = ob.minVal(1, 2 . 2 ) ;неверен, поскольку автоматического преобразования значения типа double (2.2) взначение типа i n t (тип i n t имеет массив nums в методе minVal ()) не существует.При использовании модификатора params необходимо внимательно отнестись кграничным ситуациям задания аргументов, поскольку params-параметр может принять любое количество аргументов, даже нулевое/ Например, синтаксически вполнедопустимо вызвать метод minVal () следующим образом:min - ob.minVal ();// аргументы отсутствуютmin = ob.minVal(3); // один аргументIВот поэтому в методе minVal () до попытки доступа к элементу массива nums предусмотрена проверка существования хотя бы одного элемента в массиве.
Если бы такая проверка отсутствовала, то при вызове метода minVal () без аргументов имела быместо исключительная ситуация. (Ниже в этой книге при рассмотрении исключительных ситуаций будет показан более удачный способ обработки таких типов ошибок.)Более того, код метода minVal () был написан так специально, чтобы разрешить еговызов с одним аргументом. В этом случае метод возвращает этот (единственный) аргумент.Наряду с обычными параметрами методы могут иметь и параметр переменнойдлины.
Например, в следующей программе метод showArgs () принимает один параметр типа s t r i n g и params-массив целочисленного типа.1 // Использование обычного параметра вместеI // с params-параметром.198Часть I. Язык С#using System;class MyClass {public void showArgs(string msg, params int[] nums) {Console.Write(msg + ": " ) ;foreach(int i in nums)Console.Write(i + " " ) ;Console.WriteLine();class ParamsDemo2 {public static void Main() {MyClass ob = new MyClass();ob.showArgs("Вот несколько целых чисел",1, 2, 3, 4, 5 ) ;ob.showArgs("А вот еще два числа",17, 20);IПрограмма генерирует следующие результаты:Вот несколько целых чисел: 1 2 3 4 5А вот еще два числа: 17 20Когда метод принимает обычные параметры и params-параметр, params-параметрдолжен стоять в списке параметров последним и быть единственным в своем роде.Возвращение методами объектовМетод может возвращать данные любого типа, в том числе классового.
Например,следующая версия класса Rect содержит метод e n l a r g e ( ) , который создает объектпрямоугольника как результат пропорционального увеличения (при заданном коэфшциенте увеличения) сторон вызывающего (этот метод) объекта прямоугольника.// Демонстрация возвращения методом объекта.using System;class Rect {int width;int height;public Rect(int w, int h) {width = w;height = h;}public int area() {return width * height;Глава 8. Подробнее о методах и классах199public void show() {Console.WriteLine(width + " " + height);/* Метод возвращает прямоугольник, который увеличен посравнению с вызывающим объектом прямоугольника сиспользованием заданного коэффициента увеличения.
*/public Rect enlarge(int factor) {return new Rect(width * factor, height * factor);class RetObj {public static void Main() {Rect rl = new Rect(4, 5 ) ;Console.Write("Размеры прямоугольника rl: " ) ;rl.show();Console.WriteLine("Площадь прямоугольника rl: " +rl.areaO ) ;Console.WriteLine();// Создаем прямоугольник, который вдвое больше// прямоугольника rl .Rect r2 = rl.enlarge(2);Console.Write("Размеры прямоугольника r2: " ) ;r2.show();Console.WriteLine("Площадь прямоугольника г2: " +r2.area());}}Вот результаты выполнения этой программы:Размеры прямоугольника rl: 4 5Площадь прямоугольника rl: 20Размеры прямоугольника г2: 8 10Площадь прямоугольника г2: 80В тех случаях, когда метод возвращает объект, существование этого объекта продолжается до тех пор, пока на него есть хотя бы одна ссылка.
И только когда на объект больше нет ни одной ссылки, он подвергается утилизации, т.е. попадает в поледействия процесса сбора мусора. Таким образом, объект не будет разрушен только попричине завершения метода, который его создал.Одним из применений классовых типов значений, возвращаемых методами, является генератор объектов класса, или фабрика класса (class factory).
"Фабрика" класса — это метод, который используется для построения объектов заданного класса. Вопределенных случаях пользователям некоторого класса нежелательно предоставлятьдоступ к, конструктору этого класса из соображений безопасности или по причинетого, что создание объектов зависит от неких внешних факторов. В таких случаях дляпостроения объектов и используется "фабрика" класса. Рассмотрим простой пример:// Использование "фабрики" класса.using System;200Часть I. Язык С#class MyClass {int a, b; // закрытые члены// Создаем "фабрику" класса для класса MyClass.public MyClass factory(int i, int j) {MyClass t = new MyClass();t.a = i;t.b = j;return t; // Метод возвращает объект.public void show() {Console.WriteLine("а и b: " + a + " " + b) ;c l a s s MakeObjects {p u b l i c s t a t i c void Main() {MyClass ob = new MyClass();int i, j ;// Генерируем объекты с помощью "фабрики" класса.f o r ( i = 0 , j = 10; i < 10; i++, j —) {MyClass anotherOb = o b .