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

18.7. Обобщённые делегаты "обобщённые делегаты"

Как и у обобщенных методов, у обобщенных делегатов два списка параметров

– список типизирующих параметров и список параметров методов, которые может

представлять делегат. Но у делегата нет тела, и этим обобщенный делегат

"обобщённые делегаты" похож на прототип обобщенного метода.

В качестве примера приведем обобщенный делегат с одним типизирующим

параметром:

delegate R DelMin<R> (R x, R y);

Типизирующий параметр R специфицирует типы параметров и тип

возвращаемого значения того метода, который может представлять экземпляр

реализации делегата.

В следующем классе Program два статических метода, каждый из которых

возвращает минимальное из значений своих аргументов и может быть представле

н

обобщенным делегатом. Метод minI() соответствует делегату DelMin<int>, а метод

minL() – делегату DelMin<long> (программа 18_08.).

class Program{

static int minI(int a, int b) {

return a > b ? b : a;

}

static long minL(long a, long b) {

return a > b ? b : a;

}

static void Main( ) {

int first = 5, second = 6, third = 7;

DelMin<int> dI2 = new DelMin<int>(minI);

DelMin<long> dL2 = new DelMin<long> (minL);

Console.WriteLine(dL2(dI2(first, dI2(second, third)), -3L));

}

}

В методе Main() объявлены два экземпляра (dI2 и dL2) конкретизаций

DelMin<int> и DelMin<long> обобщенного делегата DelMin<R>. Экземпляры

делегатов представляют методы

minI() и minL(). В аргументе метода

Console.WriteLine() выражение с вложенными обращениями к экземплярам

делегатов вычисляет минимальное из значений трех переменных типа int и

константы -3L типа long "тип:long" . Результат, конечно, равен -3. Обратите

внимание, что возвращаемые значения метода minI() имеют тип int, а аргументы

метода minL() должны иметь тип long. Соответствующие приведения типов при

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

не имеет отношения ни к делегатам, ни к их обобщениям, а связно с автоматическим

преобразованием арифметических типов языка C#.)

В библиотеку стандартных классов платформы .NET Framework включено

семейство обобщенных типов делегатов "делегаты:семейства обобщённых типов" ,

наиболее важными из которых для конечного пользователя являются Func<> и

Action<>. Их назначение – обеспечить программиста обобщенными делегатами,

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

Каждый из названных обобщенных делегатов перегружен, так что в пространств

е

имен

System

есть

обобщенные

типы

делегатов

с

разным

количеством

типизирующих параметров. Для обобщенных делегатов "делегаты:Func" Func<>

можно использовать от 1 до 17 типизирующих параметров. В каждом из этих

семнадцати обобщенных типов последний из типизирующих параметров определяет

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

делегат. Объявления первых трех обобщенных типов делегатов из библиотеки .NET

имеют такой вид:

delegate TResult Func<TResult> ();

delegate TResult Func<T1, TResult> (T1 t1);

delegate TResult Func<T1, T2, TResult> (T1 t1, T2 t2);

Реализации

первого

из

перечисленных

обобщенных

типов

делегатов

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

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

делегата. Например, метод с заголовком double method() может быть представлен

экземпляром делегата Func<double>. Метод с заголовком int count(int[ ] arr) может

быть представлен экземпляром делегата Func<int[ ], int> и т. д.

В отличие от делегатов Func<> делегаты

"делегаты:Action"

Action<>

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

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

void. Таких обобщенных типов делегатов в библиотеке шестнадцать с количеством

типизирующих параметров от 1 до 16:

delegate void Action<T1> (T1 t1);

delegate void Action<T1, T2> (T1 t1, T2 t2);

delegate void Action<T1, T2, T3> (T1 t1, T2 t2, T3 t3);

Например, метод с заголовком void printArray(float [ ] arr) может быть

представлен экземпляром делегата Action<float [ ]>.

Зная о существовании этих двух семейств обобщенных типов делегатов и о

том, что они известны в пространстве имен System, программист в ряде случаев

может не включать в код собственное объявление регулярного типа делегата

.

Например, если в программе нужен тип delegate int Processor (string line, char ch),

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

char, возвращающие значение типа int, то можно использовать Func<char, string,

int>.

Следующая программа иллюстрирует применение библиотечных обобщенных

типов делегатов Func<> и Action<>. Необходимо написать метод для формирования

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

метод для вывода в консольное окно значений элементов одномерного массива. В

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

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

Фибоначчи (программа 18_09.cs):

// Обобщенные делегаты .NET и обобщенный метод

using System;

class Program {

static void printArray<T>(T[ ] ar, string format) {

foreach (T z in ar)

Console.Write(format, z);

Console.WriteLine( );

} // printArray<T>( )

static int[ ] fib(int numb) {

int[ ] ar = new int[numb];

ar[0] = ar[1] = 1;

for (int k = 2; k < numb; k++)

ar[k] = ar[k - 1] + ar[k - 2];

return ar;

}

static void Main( ) {

Action<int [], string> act =

new Action<int[], string>(printArray);

Func<int, int[]> result = new Func<int, int[]>(fib);

act(fib(7),"{0} ");

}

}

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

1 1 2 3 5 8 13

Обобщенный метод printArray<T>() для вывода значений элементов массива

мы уже приводили. В этой программе он немного изменен – исключено

умалчиваемое значение второго параметра, а в теле метода для перебора элементов

массива применен цикл foreach. Для представления такого метода можно

использовать экземпляр реализации обобщенного делегата Action<T1>. Обратите

внимание, что второй параметр обобщенного метода printArray<T>() не типизирован

и имеет фиксированный тип string.

Метод для создания массива со значениями членов ряда Фибоначчи fib(int

numb) особенностей не имеет. Параметр определяет число членов ряда,

возвращаемый результат – ссылка на создаваемый массив. Для представления

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

Func<T1, TResult>.

В основной программе (в методе Main) ссылка Action<int [ ], string> act

связана

с

экземпляром

делегата,

представляющим

конкретизацию

метода

printArray(). Первый типизирующий аргумент int [ ] обобщенного делегата Action<

> определяет тип первого параметра метода void printArray<T>(T[ ] ar, string

format), а второй типизирующий аргумент соответствует фиксированному типу

второго параметра метода. Ссылка Func<int, int[ ]> result связана с экземпляром

делегата, представляющим метод int[ ] fib(int numb). После объявления указанных

ссылок на экземпляры делегатов выражение act(fib(7),"{0}

") обеспечивает

обращение к конкретизации метода printArray<T>(), который в свою очередь

вызывает метод fib(int numb).

Контрольные вопросы

Назовите языки программирования, в которых тем или иным способом реализован

механизм обобщений.

Какие типы языка C# могут объявляться как обобщённые?

Какие члены типов языка C# могут быть обобщёнными?

Назовите обязательные элементы декларации (объявления) обобщённого класса.

Что такое типизирующий параметр?

Каково назначение типизирующих аргументов в обозначении специализированного

типа

?

Что такое сконструированный тип?

В чём отличия сконструированного типа от регулярного типа?

Назовите требования к именам типизирующих параметров.

Объясните

назначение

раздела

ограничений

типизирующих

параметров

в

декларации обобщённого типа и обобщённого метода.

Какой формат имеет элемент списка ограничений типизирующих параметров?

Назовите виды ограничений типизирующего параметра.

Что такое свободные типизирующие параметры?

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

Когда применяется ограничение с помощью явного указания типа?

Назовите ранги и правила использования разных форм ограничений типизирующих

параметров.

Объясните правила перегрузки обобщённых типов.

Почему обобщённый тип называют открытым типом, а сконструированный –

закрытым?

Назовите особенности статических членов обобщённых типов.

Что определяют типизирующие параметры обобщённого интерфейса?

Как реализуется обобщённый интерфейс регулярным типом и обобщённым типом?

Как реализуется регулярным типом несколько сконструированных интерфейсов?

Назовите типы, не допускающие обобщений.

Приведите формат объявления обобщённого метода.

Что такое инстанцирование обобщённого метода?

Перечислите элементы объявления обобщённого типа делегата.

Что определяют типизирующие параметры обобщённого типа делегата.

Назовите

имена

обобщённых

типов

делегатов,

входящих

в

библиотеку

классов .NET.

Литература

C# 3.0. Language Specification. Version DOCPROPERTY Version \*

MERGEFORMAT 3.0. : Microsoft Corporation. DOCVARIABLE Version

\* MERGEFORMAT . 2007. – 504 pp.

ECMA-334. C# Language Specification. 4th Edition / June 2006, -

Geneva (ISO/IEC 23270:2006). – 553 pp.

Бадд Т. Объектно-ориентированное программирование в

действии. – СПб.: Питер, 1997. – 796 с.

Гросс К. C# 2008 и платформа NET 3.5 Framework: :базовое

руководство, 2-е изд. – СПб.: БХВ-Петербург. 2009. – 576 с.

Либерти Д. Программирование на C#. . – СПб: Символ-Плюс,

2003. – 688 с.

Морган М. Java 2. Руководство разработчика. – М.: "И.Д.

Вильямс", 2000. – 720 с.

Н е й г е л К . и д р . C# 2008 и п л а т ф о р м а .NET 3.5 д л я

профессионалов. – М. : ООО "И.Д. Вильямс", 2009. – 1392 с.

Нэш Т. C# 2008: ускоренный курс для профессионалов. – М. :

ООО "И.Д. Вильямс", 2008. – 576 с.

Петцольд Ч. Программирование в тональности С#. – М.:

Издательско-торговый дом "Русская Редакция", 2004. – 512 с.

Рихтер Дж. CLR via C#. Программирование на платформе

Microsoft .NET Framework 2.0 на языке C#. Мастер класс. 2-е изд.

исправ. . – М. : Русская Редакция; СПб.: Питер, 2008. – 656 с.

Скит Дж. C# ; программирование для проффесионалов. 2-е изд./

Д.Скит. – М.: ООО "И.А. Вильямс", 2011. – 544 с.

Страуструп Б. Язык программирования С++. 3-е изд. – СПб.; М.:

"Невский Диалект" - "Издательство БИНОМ", 1999. – 991 с.

Троелсен Э. С# и платформа .NET 3.0, специальное издание. –

СПб.: Питер, 2008. – 1456 с.

Фролов А.В., Фролов Г.В. Язык С#. Самоучитель. – М.: ДИАЛОГ-

МИФИ, 2003. – 560 с.

Шилдт Г. Полный справочник по С#. – М.: "И.Д. Вильямс", 2004.

– 752 с.

Предметный указатель

INDEX \e "

" \h "A" \c "2" \z "1049

"

А

автоматически реализуемые свойства

автоматические преобразования типов

автореализуемые свойства

аксессор

аксессор доступа

аксессор изменения

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

аргумент

аргументы разных типов

командной строки

передача аргументов по значению

приведение типов аргументов

база класса

базовые (первичные) операции

базовые типы значений

библиотека классов – FCL

библиотечные типы

блок

try/catch

блок контроля

завершения

вещественные типы

вещественным типам

выражение

226

47

227

221

222

222

351

151

160

141

164

160

369

31

28

62

23

320

320

321

25

47

Б

В

инициализирующее выражение

праводопустимое

глубина рекурсии

декларация аксессора доступа

декларация аксессора изменения

декларация обобщённого класса

декларация свойства

декомпозиция строк

декремент

делегат

вызов делегата

многоадресный экземпляр делегата

определение делегата

экземпляр делегата

делегаты

Action

Func

семейства обобщённых типов

деструктор

имя_деструктора

123, 290

125

Г

168

Д

221

222

368

221

135

35, 294

337

337

344

337

339

389

388

388

213

21

3

десятичной переменной

десятичный тип

диаграмма агрегации

диаграмма композиции

динамическое связывание

дополнительный код

защищённые члены

идентификатор

иерархии интерфейсов

изменение строки

именованные константы

имя_интерфейса

индексатор

вызов индексатора

модификаторы_индексатора

объявление индексатора

тело индексатора

индексирующее_выражение

инициализатор

инициализирующее выражение

инкапсуляция

принцип инкапсуляции

инкремент

инстанцирование

интерфейс

IComparable

иерархия интерфейсов

наследование интерфейсов

неявная реализация интерфейсов

реализация интерфейса

спецификаия базы интерфейса

интерфейс как тип

исключение

System.FormatException

System.IndexOutRangeException

исключения

System.NullReferenceException

генерация исключений

генерация исключения

обработка исключения

квалифицированное имя

класс

ArrayList

Data.Time

Enum

string

System.Delegate

System.Exception

System.Object

52

25

239

240

258, 279

41

З

247

И

9, 28

282

143

30

267

228

229

229

228

229

100

103

27

216

216

35, 294

337

265, 266

312

284

281

275

309

282

276

322

325

316

331

330

318

318

К

177, 291

7, 8

307

360

296

122

337, 344

318, 335

29

9

System.SystemException

Thread

абстрактный класс

агрегация классов

базовый класс

вложение классов

внутренний класс

генерации событий

класс object

класс System.Еnum

множественное наследование классов

модификатор_класса

наследование классов

обработки событий

определение класса

отношения наследования классов

производный базовый класс

спецификация базы класса

статические члены класса

статический класс

тело_класса

член класса

композиция классов

конкатенация

конкатенация строк

константа перечисления

константы

объявление статической константы

конструктор

базового класса

имя конструктора

инициализатор конструктора

инициализатор_конструктора

конструктор базового класса

конструктор объектов

конструкторы классов

копирования

общего вида

объявление статического конструктора

приведения типов

статический конструктор

тело конструктора

умолчания

конструктор исключений

Exception()

Exception(String)

Exception(String, Exception)

конструктор умолчания

копирование

поверхностное копирование

поразрядное копирование

335

357

259

239

243

241

242

361

20, 23

292

269

191

243

361

191

246

244

270

175

188

175, 192

192

237

13, 57, 128

127

291

181

181

67, 123, 135

245

206

251

207

251

206

186

208, 211

208, 211

186

208, 211

186

207

208, 212

330

330

330

200, 300

119

119

Л

литерал

регулярный строковый литерал

строковый литерал

литералов

122

122

3

0

логические выражения

булевы выражения

логический

логический тип

53

25

52

М

массив

копии массива-объекта

копия массива

массив массивов

массив ссылок на массивы

массив ссылок на строки

массив-список

непрямоугольные массивы

объект-массив

одномерные массивы

одномерный массив

размерность массива

ранг массива

ссылки на массив

тип массива

массивы делегатов

машинный нуль

машинным нулём

метка

метка default

метка переключателя

метод

Add()

Array

Array.Sort()

Combine

Compare()

CompareTo()

Format

get method

GetInvocationList

Join()

Parse()

Remove

set method

Sort()

Split()

ToString()

абстрактный метод

виртуальные методы

заголовок метода

косвенно рекурсивный

косвенно рекурсивный

метод Array GetValues

метод Format

метод GetName

метод GetNames

метод GetUnderlyingType

метод IsDefined

метод Parse()

метод Sleep()

109

110

113, 117

115

134

307

113

102

108

100

110, 111

113

101

110

342

90

51

96

133

11, 64

307

108

171, 312, 352

344

136

312

129

217

344

135

139

345

217

171

135

125, 138

259

254

147

166

167

297

297

296

297

296

297

69

35

7

метод TryParse()

метод–процедура

метод–функция

модификатор метода

модификаторы метода

нестатические методы

нестатический метод

опечатанный метод

определение метода

перегрузка методов

прототип метода

сигнатура метода

статический

статический метод

статический метод класса

тело метода

экранирование методов

минимальная функциональность

модификатор

new

out

override

protected

ref

sealed

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