Использование делегата для передачи метода в качестве параметра в другой метод

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

S1 =

S2 =

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

S = .

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

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

Ключевое слово delegate используется для объявления ссылочного типа. Делегат это тип, который определяет подпись метода и его можно связать с любым методом с совместимой подписью.

Пример 5.5. В качестве примера приводится программа для решения рассмотренной выше задачи вычисления двух сумм.

using System;

class Program

{

delegate int fi(int i);

static int f1(int i)

{

return i * i;

}

static int f2(int i)

{

return i * i * i;

}

static int si(fi f, int n)

{

int s = 0;

for (int i = 0; i <= n; i++)

{

s = s + f(i);

}

return s;

}

static void Main()

{

int s1 = si(f1,12);

int s2 = si(f2,7);

Console.WriteLine("{0} {1}", s1, s2);

}

}

 

 

 

Следующие примеры демонстрируют использование метода в качестве параметра, а также использование перечисления для вычисления определенного интеграла двумя различными методами.

Пример 5.6. Оформить функцию для вычисления S = . Используя эту функцию, вычислить S1= sin xdx и S2= 1/ dx. Для вычисления определенного интеграла использовать метод трапеций. Разделим отрезок [a,b] на n отрезков длиной h=(ba)/n. Формула трапеций для вычисления интеграла в этом случае имеет вид

h/2(f(a)+f(b)+2 ),

где x1 = a+h, x2 = a+2h, ..., …

Выберем n =20 для вычисления S1 и n =30 для вычисления S2.

using System;

class Program

{

delegate double fx(double i);

static double f1(double x)

{

return Math.Sin(x)*Math.Sin(x);

}

static double f2(double x)

{

return 1/Math.Sqrt(9 + x * x);

}

static double sw(fx f, double a, double b, int n)

{

double c = 0, x = a, h = (b - a)/n;

for (int i = 1; i < n; i++)

{

x += h; c += f(x);

}

return (2 * c + f(a) + f(b)) * h / 2;

}

static void Main()

{

double s1 = sw(f1, 0.0, Math.PI/2, 20);

double s2 = sw(f2, 0.0, 2.0, 30);

Console.WriteLine("{0:f4} {1:f4}", s1, s2);

}

}

Пример 5.7. Оформить функцию для вычисления S = . Используя эту функцию, вычислить S1= sin xdx и S2= 1/ dx. Для вычисления определенного интеграла использовать метод трапеций и метод Симпсона. Для выбора метода использовать перечисление (см. п. 1.6).

Разделим отрезок [a,b] на n отрезков (для метода Симпсона n должно быть четным) длиной h=(ba)/n. Формула трапеций для вычисления интеграла приведена выше.

Формула Симпсона имеет вид

h/3(f(a)+f(b)+

(ci=(-1)i+1, вычисляется как c = -c).

Выберем n =20 для вычисления S1 и n =30 для вычисления S2.

 

using System;

class Program

{

enum Method { method1, method2 };//объявление перечисления

delegate double fx(double i);

static double f1(double x)

{

return Math.Sin(x) * Math.Sin(x);

}

static double f2(double x)

{

return 1 / Math.Sqrt(9 + x * x);

}

static double sw(fx f, double a, double b, int n, Method met)

{

double s = f(a) + f(b), x = a, h = (b - a) / n;

if (met == Method.method1)

{

for (int i = 1; i < n; i++)

{

x += h; s += 2 * f(x);

}

s = s * h / 2;

}

if (met == Method.method2)

{

double c = 1.0;

for (int i = 1; i < n; i++)

{

x += h; s += (3 + c) * f(x); c = -c;

}

s = s * h / 3;

}

return s;

}

static void Main()

{

double s1 = sw(f1, 0.0, Math.PI / 2, 20, Method.method1);

double s11 = sw(f1, 0.0, Math.PI / 2, 20, Method.method2);

double s2 = sw(f2, 0.0, 2.0, 30, Method.method1);

double s22 = sw(f2, 0.0, 2.0, 30, Method.method2);

Console.WriteLine("{0:f4} {1:f4} {2:f4} {3:f4}", s1, s11, s2, s22);

Console.ReadKey();

}

}

 

Замечание.Среди параметров метода sw для вычисления интеграла имеется параметр met типа Method. При вызове метода в качестве аргумента указывается конкретный элемент списка перечисления, объявленного в начале кода, в соответствии с чем и выбирается способ вычисления интеграла в методе sw.

Вопросы для самопроверки.

1. Что такое метод. Разновидности методов: метод, возвращающий значение и метод, не возвращающий значения. Особенности их оформления.

2. Что такое подпись метода.

3. Вызов метода. Способы передачи параметров: по значению, по ссылке. Правила согласования типов параметров метода и аргументов при обращении к нему.

4. Различные возможности взаимного расположения вызываемого и вызывающего методов: в одном классе, в разных классах.

5. Особенности вызова нестатического метода из статического метода.

6. Использование массивов в качестве параметров.

7. Методы как параметры: Использование делегата для передачи метода как параметра другого метода.

 








Дата добавления: 2015-02-07; просмотров: 1345;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.025 сек.