Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

17.5. Анонимные методы

В том месте, где делегат должен представлять конкретный метод, можно

объявить экземпляр делегата, и "прикрепить" к нему тело безымянного метода.

Такой метод называют анонимным. Сигнатуру этого метода (спецификацию

параметров и тип возвращаемого значения) специфицирует тип делегата. Тело

анонимного метода

"анонимный метод"

подобно телу соответствующего

именованного метода, но имеются некоторые отличия. (Об отличиях чуть позже).

Применение анонимных методов рекомендуется в тех случаях, когда метод

используется однократно или его вызовы локализованы в одном блоке кода

программы

.

В

следующей

программе

используются

два

анонимных

метода ,

представленные двумя экземплярами делегата, определённого в глобальном

пространстве имён. Методы выполняют округление положительного вещественного

числа. Один до ближайшего целого и второй до большего целого.

// 17-05.cs - анонимные методы...

using System;

delegate int Cast (double x); // Объявление делегата-типа

class Program {

static void Main() {

double test = 15.3;

Cast cast1 = delegate(double z) // ближайшее целое

{ return (int)(z + 0.5);};

Cast cast2 = delegate(double z) // большее целое

{ return ((int)z == z ? (int)z : (int)(z+1)) ; };

Console.WriteLine("cast1(test)={0}, cast2(test)= {1}",

cast1(test), cast2(test));

Console.WriteLine("cast1(44.0)={0}, cast2(44.0)= {1}",

cast1(44.0), cast2(44.0));

}

}

Результаты выполнения программы:

cast1(test)=15, cast2(test)= 16

cast1(44.0)=44, cast2(44.0)= 44

Делегат-тип Cast предназначен для представления методов с параметром

типа double, возвращающих значение типа int. В методе Main() объявлены два

экземпляра делегата Cast, ассоциированные со ссылками cast1 и cast2. В объявлении

экземпляров делегата вместо явного обращения к конструктору делегата Cast

используется конструкция:

delegate (спецификация_параметров)

{операторы_типа_метод };

Анонимный метод, связанный со ссылкой cast1, получив в качестве

параметра вещественное значение, возвращает ближайшее к нему целое число.

Анонимный метод, представляемый ссылкой cast2, возвращает целое число, не

меньшее значения параметра

.

Анонимные методы удобно применять для "настроек" библиотечных

методов, предусматривающих применение обратного вызова.

В главе 9, посвящённой методам C#, рассмотрено применение функций

обратного вызова в обращениях к библиотечному методу сортировки элементов

массива. Там мы использовали имена методов в качестве аргументов метода

Array.Sort()

"метод: Array.Sort()" . Для этих же целей можно применить

анонимные методы, разместив их объявления непосредственно в обращениях к

методу Array.Sort().

Приведём программу, в которой элементы целочисленного массива

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

задания правил упорядочения применим в обращениях к методу Array.Sort() в

качестве аргументов анонимные методы:

// 17_06.cs - анонимные методы и Array.Sort( )

using System;

class Program

{

static void Main( )

{

int[ ] ar = { 4, 5, 2, 7, 8, 1, 9, 3 };

Array.Sort(ar,

delegate(int x, int y) // по убыванию

{

if (x < y) return 1;

if (x == y) return 0;

return -1;

}

);

foreach (int memb in ar)

Console.Write("{0} ", memb);

Console.WriteLine( );

Array.Sort(ar,

delegate(int x, int y) // по четности

{

if (x % 2 != 0 & y % 2 == 0) return 1;

if (x == y) return 0;

return -1;

}

)

;

foreach (int memb in ar)

Console.Write("{0} ", memb);

Console.WriteLine( );

}

}

Результат выполнения программы:

98754321

48279351

Так как каждый из анонимных методов используется в данной программе

только один раз, то нет необходимости объявлять тип делегатов отдельно и

определять ссылки с типом делегата. Экземпляры делегатов, представляют

конкретные анонимные методы непосредственно в аргументах метода Array.Sort().

Напомним, что делегат это тип и поэтому может не только специфицировать

параметры методов. В следующем примере делегат определяет тип свойства класса.

В решаемой далее задаче нужно объявить делегат-тип для представления методов,

вычисляющих значения логических функций 2-х переменных. Далее нужно

определить класс, объект которого заполняет таблицу истинности

"таблица

истинности" для функции, представленной в объекте полем, имеющим тип делегата.

Для обращения к полю определить открытое свойство с типом делегата.

(При заполнении таблицы истинности объект "не знает" для какой

логической

функции строится таблица. Функция передается объекту в точке обращения к его

методу.)

Определить класс со статическим методом для вывода на экран таблицы

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

значение ИСТИНА значением 1, а ЛОЖЬ - 0.

Конкретные функции передавать методу с помощью анонимных методов,

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

метод, присваивать свойству объекта.

В методе Main() определить два анонимных метода, представляющи

е

логические функции, и построить для них таблицы истинности.

// 17_07.cs - свойство с типом делегата и анонимные методы

using System;

public delegate bool BoolDel(bool x, bool y); // Делегат-тип.

public class Create // Класс таблиц истинности.

{

BoolDel specificFun; // Поле, определяющее логическую функцию

public BoolDel SpecificFun

{

set { specificFun = value; }

}

public bool[,] define() // Формирование логического массива

{

bool[,] res = new bool[4, 3];

bool bx, by;

int k = 0;

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

for (int j = 0; j <= 1; j++)

{

bx = (i == 0 ? false : true);

by = (j == 0 ? false : true);

res[k, 0] = bx;

res[k, 1] = by;

res[k++, 2] = specificFun(bx, by);

}

return res;

}

}

public class Methods // Класс с методами

{

static public void printTabl(bool[,] tabl)

{

Console.WriteLine("A B F");

for (int i = 0; i < tabl.GetLength(0); i++)

Console.WriteLine("{0} {1} {2}",

tabl[i, 0] ? 1 : 0, tabl[i, 1] ? 1 : 0, tabl[i, 2] ? 1 : 0);

}

}

class Program // Основной класс программы

{

static void Main()

{

Create create = new Create();

create.SpecificFun = delegate(bool a, bool b)

{ return a || b; };

Console.WriteLine("Таблица для (A || B):");

Methods.printTabl(create.define());

create.SpecificFun = delegate(bool d, bool e)

{ return d && !e; };

Console.WriteLine("\nТаблица для (A && !B):");

Methods.printTabl(create.define());

}

}

Результаты выполнения программы:

Таблица для (A || B):

AB F

00 0

01 1

10 1

11 1

Таблица для (A && !B):

AB F

00 0

01 0

10 1

11 0

Соседние файлы в папке CSBasicCourse2ndedPodbelsky