Программирование >>  Программирование с использованием ajax 

1 ... 46 47 48 [ 49 ] 50 51 52 ... 396


Механизм перегрузки функций (function overloading) позволяет создавать множество функций, имеющих одинаковое имя, но работающих с разными типами параметров. Например, ранее приводился код, в котором содержалась функция с именем MaxValue ():

class Program {

static int MaxValue (int [ ] intArray) {

int maxVal = intArray[0];

for (int i = 1; i < intArray.Length; i++)

if (intArray[i] > maxVal) maxVal = intArray[i];

return maxVal;

static void Main(string[] args) {

int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2}; int maxVal = MaxValue(myArray) ;

Console.WriteLine( The maximum value in myArray is {0} , maxVal);

Вывод максимального значения в массиве myArray

Console.ReadKey();

Эта функция могла использоваться только с массивами значений int. Для работы с другими типами параметров можно было бы либо предоставить соответствующие функции с другими именами, т.е., например, изменить имя на IntArrayMaxValue () и предоставить функции с именами вроде DoubleArrayMaxValue () для обработки других типов, либо добавить в код следующую функцию:

static double MaxValue(double [ ] doubleArray) {

double maxVal = doubleArray [0];

for (int i = 1; i < doubleArray.Length; i++)

if (doubleArray [i] > maxVal) maxVal = doubleArray [ i];

return maxVal;

Единственное отличие здесь связано с применением значений double. Имя функции - MaxValue () - выглядит точно так же, но вот ее сигнатура (что критически важно) выглядит по-другому. Объясняется это тем, что в сигнатуру функции, как уже рассказывалось ранее, входит как имя функции, так и ее параметры. Определение двух функций с одинаковыми сигнатурами было бы ошибкой, но благодаря тому, что эти две функции имеют разные сигнатуры, никакой ошибки здесь нет.

Возвращаемый тип функции не является частью ее сигнатуры, поэтому определять две функции, отличающиеся только типом возвращаемого значения, нельзя; их сигнатуры считаются идентичными.

После добавления приведенного выше кода у функции MaxValue () появятся две версии, одна из которых будет принимать в качестве входных данных массив значе-



НИИ типа int и возвращать максимальное значение в нем как число типа int, а вторая - принимать в качестве входных данных массив значений типа double и возвращать максимальное значения в нем в виде числа типа double.

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

Обратите внимание на еще одно свойство механизма IntelliSense в VS и VCE: при наличии в приложении двух таких, как были показаны выше, версий функции и вводе ее имени, IDE будет отображать все доступные перегрузки для данной функции. Например, в случае ввода такой строки:

double result = MaxValue (

IDE отобразит информацию об обеих версиях функции MaxValue (), между которыми можно будет переключаться клавишами со стрелками вверх и вниз (рис. 6.9).

\m оГ2ш double Program Ma)(Value(doublendoubleArray) \щ2оГ2щ int Program Ма)Л/а1ие (intnintArrajo]

Рис. 6.9. Отображение информации о доступных перегруженных версиях функции

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

static void ShowDouble (ref int val)

static void ShowDouble (int val)

Решение no поводу того, какая версия должна использоваться, будет приниматься на основании того, содержится в вызове функции ключевое слово ref или нет. Например, следующая строка кода приведет к вызову той версии, которгш принимает параметры по ссылке:

ShowDouble(ref val);

Показанная ниже строка кода обеспечит вызов версии, которая принимает параметры по значению:

ShowDouble(val) ;

В качестве альтернативы можно сделать так, чтобы версии функции отличались друг от друга количеством параметров и т.д.

Делегаты

Делегат (delegate) - это тип, который позволяет хранить ссылки на функции. Возможно, это звучит довольно замысловато, но на самом деле механизм делегатов выглядит удивительно просто. Самая важная задача делегатов будет демонстрироваться чуть позже в этой книге при рассмотрении событий и их обработки, но полезно



рассказать здесь о них хотя бы вкратце. Объявляются делегаты во многом так же, как функции, но только безо всякого тела функции и с ключевым словом delegate. В объявлении любого делегата указывается возвращаемый тип и список параметров. После определения делегата можно объявлять переменную с типом этого делегата. Далее эту переменную можно инициализировать как ссылку на любую функцию, которая имеет точно такой же возвращаемый тип и список параметров, как и у делегата. После этого функцию можно вызывать с использованием переменной делегата так, будто бы это и есть сама функция.

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

Тактическое занятие Применение делегата для вызова функции

1. Создайте новое консольное приложение по имени Ch06Ex05 и сохраните его в каталоге С:\BegVCSharp\Chapter06.

2. Добавьте в файл Program.cs следующий код:

class Program (

delegate double ProcessDelegate (double paraml, double param2) ; static double Multiply (double paraml, double param2)

return paraml * param2 ;

static double Divide (double paraml, double param2)

return paraml / param2 ;

static void Main(string [ ] args) ProcessDelegate process ;

Console.WriteLine ( Enter 2 numbers separated with a comma: ) ;

Введите 2 числа, отделив их друг от друга запятой string input = Console. ReadLine () ; int commaPos = input.IndexOf(,);

double paraml = Convert. ToDouble (input. Substring (0, commaPos)) ; double param2 = Convert. ToDouble (input. Substring (commaPos + 1,

input.Length - commaPos - 1)) ; Console.WriteLine ( Enter M to multiply or D to divide: ) ;

Введите если хотите вьшолнить операцию умножения, или D, если операцию деления input = Console.ReadLine(); if (input == M )

process = new ProcessDelegate (Multiply) ; else

process = new ProcessDelegate(Divide); Console.WriteLine( Result: {0} , process(paraml, param2));

Вывод результата Console.ReadKey();



1 ... 46 47 48 [ 49 ] 50 51 52 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика