
- •Оглавление
- •Об авторе
- •Посвящение
- •Благодарности
- •Ждем ваших отзывов!
- •Что такое .NET
- •Создание исходной программы
- •Тестовая поездка
- •Каркас программы
- •Комментарии
- •Введение в хитрости панели элементов
- •Повторное использование кода из панели элементов
- •Правила объявления переменных
- •Вариации на тему int
- •Объявление переменной с плавающей точкой
- •Ограничения переменных с плавающей точкой
- •Объявление переменных типа decimal
- •Сравнение десятичных и целых чисел, а также чисел с плавающей точкой
- •Логичен ли логический тип
- •Символьные типы
- •Что такое тип-значение
- •Неизменяемость строк
- •Основные операции над строками
- •Сравнение строк
- •Сравнение без учета регистра
- •Отличие строк в разных регистрах
- •Преобразование символов строки в символы верхнего или нижнего регистра
- •Поиск в строках
- •Как искать
- •Пуста ли строка
- •Удаление пробельных символов
- •Анализ числового ввода
- •Обработка последовательности чисел
- •Объединение массива строк в одну строку
- •Арифметика
- •Простейшие операторы
- •Порядок выполнения операторов
- •Оператор инкремента
- •Сравнение чисел с плавающей точкой
- •Составные логические операторы
- •Вычисление типа операции
- •Типы при присваивании
- •Перегрузка операторов
- •Ветвление с использованием if и switch
- •Инструкция if
- •Инструкция else
- •Как избежать else
- •Вложенные инструкции if
- •Конструкция switch
- •Циклы
- •Цикл без счетчика
- •Правила области видимости
- •Пример
- •Зачем нужны разные циклы
- •Зачем нужны массивы
- •Массив фиксированного размера
- •Массив переменного размера
- •Свойство Length
- •Инициализация массивов
- •Понятие <т>
- •Обобщенные коллекции
- •Инстанцирование пустого списка
- •Создание списка целых чисел
- •Преобразования списков в массивы и обратно
- •Подсчет количества элементов в списке
- •Поиск в списках
- •Инициализаторы массивов и коллекций
- •Выполнение специфичных для множеств задач
- •Создание множества
- •Добавление элемента в множество
- •Выполнение объединения
- •Пересечение множеств
- •Получение разности
- •Не используйте старые коллекции
- •Обход каталога файлов
- •Начало программы
- •Получение начальных входных данных
- •Создание списка файлов
- •Форматирование вывода
- •Вывод в шестнадцатеричном формате
- •Обход коллекций: итераторы
- •Доступ к коллекции: общая задача
- •Использование foreach
- •Формат индексатора
- •Блок итератора
- •Создание каркаса блока итератора
- •Итерирование дней в месяцах
- •Что же такое коллекция
- •Синтаксис итератора
- •Блоки итераторов произвольного вида и размера
- •Обобщенные классы безопасны
- •Обобщенные классы эффективны
- •Очередь с приоритетами
- •Распаковка пакета
- •Написание обобщенного кода
- •Использование простого необобщенного класса фабрики
- •Незавершенные дела
- •Ковариантность
- •Использование механизма исключений для сообщения об ошибках
- •Что происходит при генерации исключения
- •Исключительный пример
- •Что делает этот пример "исключительным"
- •Трассировка стека
- •Советы по написанию кода с хорошей обработкой ошибок
- •Анализ возможных исключений метода
- •Как выяснить, какие исключения генерируются теми или иными методами
- •Генерирующие исключения выражения
- •Работа с перечислениями
- •Создание перечислений с инициализаторами
- •Указание типа данных перечисления
- •Применение перечислений в конструкции switch
- •Процедурные поездки
- •Объектно-ориентированные поездки
- •Определение класса и объекта
- •Определение класса
- •Что такое объект
- •Различие между объектами
- •Работа со ссылками
- •Классы, содержащие классы
- •Определение константных членов-данных и членов-данных только для чтения
- •Передача аргументов методу
- •Передача методу нескольких аргументов
- •Соответствие определений аргументов их использованию
- •Перегрузка методов
- •Реализация аргументов по умолчанию
- •Возврат значения оператором return
- •Кортеж с двумя элементами
- •Создание кортежей более чем с двумя элементами
- •Глава 14 Поговорим об этом
- •Определение методов
- •Определение статического метода
- •Определение метода экземпляра
- •Полное имя метода
- •Ключевое слово this
- •Когда this используется явно
- •Что делать при отсутствии this
- •Использование локальных функций
- •Прочие уровни безопасности
- •Методы доступа
- •Пример управления доступом
- •Выводы
- •Статические свойства
- •Побочные действия свойств
- •Дайте компилятору написать свойства для вас
- •Методы и уровни доступа
- •Замена конструктора по умолчанию
- •Конструирование объектов
- •Непосредственная инициализация объекта
- •Конструирование с инициализаторами
- •Инициализация объекта без конструктора
- •Определение свойств с кодом
- •Определение конструкторов и деструкторов с кодом
- •Определение методов доступа к свойствам с кодом
- •Определение методов доступа к событиям с кодом
- •Наследование класса
- •Более сложный пример наследования
- •ЯВЛЯЕТСЯ или СОДЕРЖИТ
- •Доступ к BankAccount через содержание
- •Отношение СОДЕРЖИТ
- •Заменяемость классов
- •Неверное преобразование времени выполнения
- •Указание конкретного конструктора базового класса
- •Обновленный класс BankAccount
- •Перегрузка унаследованного метода
- •Простейший случай перегрузки метода
- •Различные классы, различные методы
- •Сокрытие метода базового класса
- •Вызов методов базового класса
- •Что неверно в стратегии использования объявленного типа
- •Использование is для полиморфного доступа к скрытому методу
- •Объявление метода виртуальным и перекрытие
- •Получение максимальной выгоды от полиморфизма
- •Разложение классов
- •Абстрактный класс: ничего, кроме идеи
- •Как использовать абстрактные классы
- •Создание абстрактных объектов невозможно
- •Опечатывание класса
- •Реализация интерфейса
- •Именование интерфейсов
- •Наследование и реализация интерфейса
- •Преимущества интерфейсов
- •Тип, возвращаемый методом
- •Что скрыто за интерфейсом
- •Гибкие зависимости через интерфейсы
- •Реализация отношения СОДЕРЖИТ с помощью интерфейсов
- •Определение делегата
- •Пример передачи кода
- •Делегирование задания
- •Очень простой первый пример
- •Более реальный пример
- •Создание приложения
- •Жизненный цикл делегата
- •Анонимные методы
- •Проектный шаблон Observer
- •Что такое событие. Публикация и подписка
- •Как издатель оповещает о своих событиях
- •Как подписаться на событие
- •Как опубликовать событие
- •Как наблюдатели "обрабатывают" событие
- •Сборки
- •Выполнимые файлы
- •Библиотеки классов
- •Создание проекта библиотеки классов
- •Создание автономной библиотеки классов
- •Создание классов для библиотеки
- •Использование тестового приложения
- •Дополнительные ключевые слова для управления доступом
- •protected: поделимся с подклассами
- •protected internal: более изощренная защита
- •Размещение классов в пространствах имен
- •Объявление пространств имен
- •Пространства имен и доступ
- •Использование полностью квалифицированных имен
- •Ссылочные типы
- •Выходные параметры
- •Альтернативные методы возврата значений
- •Работа с переменными out
- •Возврат значений по ссылке
- •Различия типов-значений
- •Когда следует использовать структуры
- •Добавление распространенных элементов структур
- •Управление отдельной записью
- •Добавление структур в массивы
- •Перекрытие методов
- •Определение того, что следует защищать
- •Документирование компонентов программы
- •Разложение компонентов на функции
- •Оценка рисков
- •Аутентификация с использованием входа в Windows
- •Безопасность развертывания
- •Уязвимости сценариев
- •Наилучшие методы защиты приложений Web Forms
- •Получение данных
- •Настройка образца схемы базы данных
- •Подключение к источнику данных
- •Работа с визуальными инструментами
- •Написание кода для работы с данными
- •Использование Entity Framework
- •Где водится рыба: файловые потоки
- •Потоки
- •Читатели и писатели
- •Пример использования потока
- •Как это работает
- •Наконец-то мы пишем!
- •Использование конструкции using
- •Загрузка файла из Интернета
- •Регистрация сетевой активности
- •Графика
- •Перья
- •Кисти
- •Текст
- •Классы рисования и каркас .NET
- •Приступая к работе
- •Настройка проекта
- •Обработка счета
- •Создание подключения к событию
- •Рисование доски
- •Запуск новой игры

Остальные члены мо.чо., tyQueue
Ооснхиохиа)ативл)асе омненна П tП.Са -е нлсеб-бтин ивл)а )о лросаро
Вснени)оооинцлоннеое)л .qраонпцод'нд) о)онман)лае халнд гнеиео8 )нла
р сел)еи вннеоил)еа еоииоциеоъеаеепе еаллео)ее)нелроницц)нрл)ен)ок |
||
на ИеССао е лооцл)оарt рса ла П |
tП.С |
щоонб) б)арон ораха)ал |
иоснхице орсиме)аен)онп ро)оепноохоеаваи)росемнл)ооВснени)ооо рак |
||
оноцехоив)енииеромненннцисWлзб |
лбрб !llб |
В)оеоон) лсезрое еиок |
онеаллраха)ао )ое раренасехооаиаомненнал иееоее)н)аее8wнеое)нлоои енасеха еилреп)оцг
Использование простого необобщенного класса фабрики
|
.0.. 4 цs.4. М |
И5 #sгб#4.s #П |
.a1 .П1 |
a9sМь.0.1. |
И#1#a. #П .a1#4 |
1 И. |
5# 5s |
рд.0Сr И1 |
#1 1.1.r |
.aa.a 1#ПСs#9.40# И#41#1 r |
|
.ц# б9.5г |
|
|
|
|
1г
См5.45..дa 5
ГЛАВА 8 тЭоЭодее ойтWи г.яи

Класс PackageFactory имеет один член-данные и оди н метод. (Простую фа брику можно реализовать не как класс, а как метод, например метод в классе Program.) При инстанцировании объект PackageFactory создает объект класса Random и сохраняет ero в члене-данных rand. Random представляет собой би блиотечный класс .NET, который генерирует случайные числа.
Использование мыыИылбйыыхчс,
Для генерации объекта Package со случайным приоритетом вызывается ме тод CreatePackage ( ) объекта фабрики:
|
s 3 |
, |
s К F F |
FF |
( |
Метод CreatePackage ( ) запрашивает у своего генератора случайных чисел число от О до 2 включительно и использует это число для установки приори тета нового объекта типа Package, возвращаемого данным методом (который затем сохраняется в переменной типа Package или, еще лучше, в переменной типа I PrioritizaЬle).
Обратите внимание на то, что метод CreatePackage ( ) возвращает ссылку на I PrioritizaЫe, что является более обобщенным решени ем, чем возврат ссылки на Package. Это пример C,f Ns fu- ме
ЗАПОМНИ! тод Main ( ) обращается к Package опосредованно, через интерфейс, который реализует Package. Косвенность изолирует метод Main ( ) от деталей возвращаемых методом CreatePackage ( ) объектов. Это обес печивает большую свободу в плане изменения реализации фабрики без влияния на метод Main ( ) .
Еще немного l'ltyQфабриках
Фабрики очень удобны для генерации большого количества тестовых дан ных (фабрика не обязательно использует генератор случайных чисел - он потребовался для конкретной демонстрационной программы PriorityQueue). Фабрики усовершенствуют программу, изолируя создание объектов. Каждый раз при упоминании имени определенного класса в вашем исходном тексте вы создаете N д (dependency), от этого класса. Чем больше таких за висимостей, тем больше степень связности классов, тем "теснее" они связаны между собой.
Программистам давно известно, что следует избегать тесного связывания. (Один из м ногих методов чЕ C(decoupling) заключается в применении фа брик посредством интерфейсов, как, например, I Prioriti zaЫe, а не конкрет ных классов наподобие Package.) Программисты постоянно создают объекты
,ic |
ЧАСТЬ 1 т1нолр СооВоеооао оленая не вп |

new, и rнороснх0орхя исханиахм дaрхао иьиокоыоехриумхзсиа нойун ьaукхно аоa нуруу нуьро ьеяыхррпнц х ькуaоехнукороцзокуу зизаинм
Незавершенные дела
PriorityQueue еьу у.у рлйaхунья е рузоко5оа aосхзонауu
>>Сам по себе класс PriorityQueue не защищен от попыток инстан цирования для типов, например, int, string и Student, т.е. типов, не имеющих приоритетов. Вы должны наложить ограничения на класс, чтобы он мог быть инстанцирован только для типов, реа лизующих интерфейс I PrioritizaЫe. Попытки инстанцировать
PriorityQueue для классов, не реализующих I Prioriti zaЫe,
должны приводить к ошибке времени компиляции.
»Метод Dequeue ( ) класса PriorityQueue возвращает значение null вместо реального объекта. Однако обобщенные типы напо добие <Т> не имеют естественного значения null по умолчанию,
как, например, int или string. Эта часть метода Dequeue ( ) также
. требует обобщения.
Добавление ограничений
.n33 PriorityQueue aокйур зпно ьиоьозур ыхисоьинол иону.хунозо е ойусуaо озyуанх о узо исиосинунуеCкя rнозо еьу акхььпц озlуанп аоносеe нозлн зпно схыну.ург е PriorityQueue, aокйре сухкиыоееехноирнусмуаь I Prioriti zaЫe, аха rно aукхун акхьь Package. окхьь Package лахыпехун ирнусмуаь IPrioritizaЫe е ыхзокоеауьеоузо озyяекурияw
class |
Package : IPrioritizaЬle |
|
|
|
|
|
|
|
||
.оьку |
|
rнозоор сухкиылуньеоаьнеоPriority ирнусмуаьх IPrioritizaЫe. |
||||||||
|
|
СООЕТ!ЕТЕТЕТЕТ!R3oОrСЧНЧЕТЕТ/ЕТНЧЕТНЕТОЕТХОoЧЗОoПНPriorityQueue. tлйе |
||||||||
|
|
роцйнозп аонижкянос рунуaкурро ьооз.хк |
о исозкунхe |
иси иоипн' |
||||||
|
|
ауьоыaхноrаыуникяс aкя ниихцаоносеа ру сух0иылунIPrioritizaЫe. |
||||||||
ЗАПОМНИ! |
оонликянос е ктзон |
ьклнху ьоозиин оз о5изауц уьки оaир жыну, |
||||||||
|
|
ноaое озоз иуррозо акхььх епыоеун нуноaц оньлньнелт.иа |
л ниихц |
|||||||
|
|
aкя аоносозоирьнхрлислунья озоз-уррпа акхььедaрхао клй5у иьQ |
||||||||
|
|
иокоыоехнояереу ограничения. |
".5" |
25c3. |
("3.-. |
3'.-\' 3'"3\-2 |
||||
|
|
"1"1g.''.2 |
5* \.. 1c53\*2'" |
*0*41" |
" -3b\m |
"*3.' |
1.-2 |
.b"."1 |
||
|
|
c5\f\-2 |
5"(b3*0- "'c |
m5\53. -3b. |
"bc.- |
(. \ 5\5 |
. |
'.- |
|
ГЛАВА 8 зчеч,ро оеВя? аnь

·))
))
))
имя базового класса, от которого должен быть порожден класс т (или должен быть этим классом);
имя интерфейса, который должен быть реализован классом т, как было показано в предыдущем примере;
прочие ограничения, показанные в табл. 8.1 .
мй брранл' мнлян сбьнб врб'мотм в раьлочо ф:ф з -:. |
9 одравб: . 'Ы |
нбжолотост вб яьтеы лс/ |
|
Таблица 8.1 . Варианты обобщенных ограничений |
|
'бн. сн1й.сс
атрбйeлоофьлa
Аиокьиa
япдолжно быть (или расширять) |
чзлолai h трa lф АлnвфААa |
||
трафsлnвфssa |
|
|
|
т пв 0eьвC н) у0дгвзи зуасC |
чзлолai D атрбйилоa |
dфьлa |
|
еiра\tл( |
Еффлa |
|
|
т пв1eьвC |
о;y,C 0oоичC адчв ч=гьу>> |
чзлолai E aАиокьиa |
|
а)ьд)чC |
|
|
|
ьвфААa |
т должно быть любым ссылочным |
чзл олai F aь,фААa |
|
6дывчC |
|
йлч е а a |
ксдолжно иметь конструктор без |
чз лолai h aйлчaтаaa |
|
параметров |
|
мйратлтм внлсанлм |
на брранлйонля Аиокьрaл ь, фАА+еаьанa |
ло Аиокьиaбьна, |
|
'аот Т'тб |
сбьмт еттм |
йтс тлвб сvьна'мнлосL 'локбвтс тлвбсг ьзфо#aниивa |
|
лкл кййтс |
бй>ме0бсt бй>явкмннтс оловбкмьбванлос екй'овбоб окбва Аиокьи+a |
218 ЧАСТЬ 1 Основы программирования н а С#

ТЕХНИЧЕСКИЕ s0ЗАe0CЕ!!f \ ТЕХ\ |
! ,ТЕХООПНП. ЕО!ИО М\""ОНКОПНОН! !ПИ ПОИ |
|
\ОНЕПСММППТЕХfТЕХp |
) .. |
|
|
|
|
Е |
Е |
,S |
o!И\Н Пa ПМ!МОИ!ПИ ПОИ\ОНЕПСММППТЕХfННКТЕХ!И!ИИИСИ КН""БОaЕМТЕХРОИНПНБ ОeННИМММПНИООМ"" ОЗ)ИПОНЕМПОООН; aИНИН!МКЕРОМИОИН!ИЗ\ f0Cf0 e0 ! ТЕХТЕХ
..ООННБОeННИМММПНИООМ"" ОЗ)ИПОНЕМЕ; ПОООНaТМЕИИО\БПОИ\ОНЕПООН""О ЕЕО! НИМРoЗИК""НННЕИОНОП!1.
Определение значения null для типа 2-de:Eaul3 |
t (TJ |
|
|
|
|
||||||||||||||
|
(. 6 |
-'4>)-(.'4>Сw -(-(( |
6 .(J.'4>o'4> |
.) |
( (С.w С.'4>( 8-(к(-)( |
'4>6-'4>.к(-)S |
|||||||||||||
'4>8-(к(SЕ(( |
-)к.'4> |
..4 |
|
.(--'4>o'4> |
.) |
(Г |
.4 |
за |
|
) .-l6o)de.) |
'4>. к)С(. |
||||||||
Л.'4> |
).) |
•Г |
.4 |
|
|
Л.'4> |
И |
( ..l4 |
.С(deССТ. '4>к-Тde.) |
'4>. |
.(.)de |
.(. |
|||||||
Ий И Лl.'4> з |
Г |
.4 |
|
а |
з.(. |
) |
..4 |
|
-'4>к)deССТ.'4>к-Тde .) |
'4>. |
Л.'4> 8-(к( |
||||||||
-)( |
з |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
и.-(.'4> |
'4>С'4>..w.6 '4>7'4>7Е(--ТB |
..(СС -( |
|
'4>.'4>7)( |
|
|
а |
l -'4>J(l. |
|||||||||||
7Т.w )-С.(-Б)-'4>.(- |
|
-(..)к(С.) |
..4 |
.S7'4>o'4> |
.) |
( .(--Тde |
б |
-( . С'4>С.'4>4-)) |
|||||||||||
-(.С.( 8(.w .(.)- |
.'4>.J-'4> |
7Т.w |
|
-(.).w-'4>( |
8-(к(-)( |
з |
. |
)Сde'4>.-'4>- |
.(. |
||||||||||
С.( |
'4>7'4>7Е(--'4>o'4> |
..(СС( |
|
( |
-)-(- . |
-(.'4>.( |
|
|
l |
|
l ..(ССl ( |
|
|
l а l |
|||||
.Т |
-'4>J(.( |
'4>.(8(.wС4 )-(--'4> |
. .(.'4>B |
С).6(Б)) |
|
.Т .Т8Т.((.( |
l |
l |
-l'4> |
||||||||||
'4>к(-(.w |
6С.() |
(.(.'4>. |
-(.Г |
.'4>.Т |
.'4>.J-Т |
|
.(--6.w |
к.'4> |
7Т -'4>o.'4> '4>8-(к(.w |
||||||||||
-)к(o'4> |
о'4>С.'4>.w.6 |
|
ИйИ |
l |
..(СС |
С.(.6(. |
.(--6.w |
8-(к(-)( |
з |
.'4> |
|||||||||
С'4>'4>7Е). .Т8Т.(SЕ(-6 |
|
-(.'4>.6 |
к.'4> -)к(o'4> |
.(--6.w |
-( |
6.(.'4>Сw .Т8Т.(SЕ)B |
|||||||||||||
-( |
. С(-'4> С'4>7'4>B .'4>.J(- |
|
|
-'4>.(-4.w -( |
.(--6.'4>Сw |
.) |
8-(к(-)( |
з |
• |
|
ГЛАВА 8 тaоaод ее ойтWи 4oби

|
t, !r!! |
,!,d !! |
!,D!! |
rd!e !!B |
!!!!! |
!!EM!D,!,; |
!!,D,; |
t |
D!!j,e |
||||||||
|
!,! |
!!!!!! |
,-,-e!!!,P, |
|
!!!!!!ЕТ r,!!,!B!,; |
,-,-e!!!!B |
|
! |
!!! |
!,D!! |
|||||||
ЗАПОМНИ! |
-!!B |
!!!!!!d!d,D!! |
e!, |
!E-!j |
!!r,D |
e!! |
!!jd |
o,! |
r,M!!,; |
D!!j,e |
|||||||
!,! |
!!!!!! |
!!! ,e! |
|
t!!rt |
,!B-i,;!!!, |
!!!e,;Ee!, |
|
!,!!!d,;!d!, |
|||||||||
|
|
|
|
t |
П |
!.i |
|
|
! |
|
|
|
|
|
|
|
|
П!! |
!!d,!! |
,;!D-i!D!!! |
!,!r!!,!,d,; |
M!,!,;D!, |
r,!!,!d!!BЕТ M!, !,-,B |
rd!ei |
|||||||||||
!!!D!,!! |
!!r |
! |
D!d!,;!B D!d!,! -i!!M!!!! |
|
|
e!, |
ЗА!,P,!!r! |
|
КИ!, |
|
emet |
||||||
!,!,d!B |
D!!M!!!D! |
!!!!!! |
rd!e!!!D!,!! |
!,-,B |
!!!!,M! |
!B |
!!r |
D!d!!! |
D,-iDd!i |
||||||||
e!!!!! |
-i!!M!!!!! |
|
-,;e!! |
tААdle!!!, |
e!, |
!!!,!,d!j |
ed,;P!j |
ЗА!,-i!!M!!!! |
|||||||||
!,D!! |
-!!B !!!!t |
|
! !,!r! |
!, ,d!!,D!! |
D!d!, |
,rd!e!!!!B |
M!,!!!!!, |
!!!e,;!! |
D!d!,;!Bd
n,ресм.отр_ 06Qбще1:1н9сти
-N",. -.-.O"'1'1-)($Е |
J1"#,$.-.#'1'1#- |
. |
weщJJy.,,# '1"r- ,'1- a.-.O"'1_ |
|||||||||
'1-)(. _-J1-E# |
N,- -.,"1."'1$- |
.$.'1$ |
rJ1-1J1#(,1(,1$)(#Е |
'1- . |
в(-(,1 .#J1$#'1(" |
|
-'1# |
|||||
(,1#,- .(- |
N",#,# N,- -.,"1."'1$- |
|
.$.'1$ |
#'1#,$($,# ) |
"" r-(,1-O.. |
.,,- |
-."'1. |
|||||
(J1-N'1- )(,1-N",$J1-.#(. |
J1"#,.'1-. |
|
.$.'1") |
(,1-N",.n |
$(-#D$- |
$.(,1"'1$,#). |
. |
w |
||||
t1JJyJJ -(- . |
weщJJy.)" |
r#J1#(,1"(J1, |
N-r-),#.( |
.#J1$#'1('1-)(. |
. |
'1"),-,.,$_ |
|
'1#_ |
||||
rJ1#., "'1$-_ |
в(- '1" (#, |
. ),-.#" |
-.-.O"'1'1,_ |
|
,, #))-. |
|
|
|
|
JJКо |
||
Л#J1$#'1('1-)(. |
).-.#'1# |
) ($r#(,1$ |
r#J1#(,1"(J1-. |
$ .-..J1#O#"(,1,_ |
|
.'1#."'1 $. |
|
|||||
,) 42)тeтл)e, |
ыдраюаосщюсы,мдонтптr тыцмпалланыеос илтыподычасолтсанщ |
|||||||||||
зцо ыеицаослт,мдонтптrrыцисополмызымпаллаrч сычrонт мамrл тe4),) |
|
42= |
||||||||||
)тeтл)e, |
ыдраюаосщюсысан, зцо ыеицаослт,мдонтптr тыцмпаллаЧныеос илo |
тыподычасолт,мдонтптrлбтоrмпаллаоtызца ри сыщри цrбзыорочыдныеры,:сы радячаослт2т,)42 )тeтл)e ,9о
бло тдями юосчоrызыстымыпоритыццоrеичажс ытrоцопоррбжчаrиарсo рылсоьб #е i.т и иыпооrаррие чоrлите таrаносrя мычаrиарсря,а ситя чыдo
чrагаоняе драюориьу |
мырсrачаrиарсряоесы rаиысаоt, тысынбюсылсrымычяо |
|||||
и Lоеыюилпорряотаrаносrя мычаrиарсрятаrаносrанлыи-омсанe |
||||||
т :) |
A)ш |
р:, |
", |
1,Jш рiр |
нр'l ,) |
4,", ш1, s |
:- |
н ,",4 |
ш1, |
и . им |
r r, |
ш1, |
, a |
|
срим |
рйr,eх: |
,r:им, т 4," , |
|||
цц |
г |
|
|
и уsa |
|
|
", |
ш1,Jрiр тт |
|
|
|
|
|
", |
ш1,Bрiр н l a) й ) ss |
|
|
|
лла, |
,з..ф, э, eеоеыn, oиеnитт сиеыосо, о, мч, |

А следующий код работает, потому что типы возвращаемых объектов кон травариантны строковым и целочисленным возвращаемым типам (например):
р'l ,( |
5,", |
ш1,. ", 5р,I5ш C, I5,", |
ш1, d , V |
Обобщенные типы являются инвариантными в С# 2.0 и 3.0. Это означает, что типы юонпев(о тт геНnи юонпев(ссsаnвНнеn являются взаимозаменяемыми, как строки и объекты в предыдущем примере.
ттобтизидьзйе
Если вы посмотрите на метод, подобный следующему
т |
:( |
|
:(ш |
р:, |
eх: ", |
|
ш1, |
d , |
|
|
|
г: |
рг,", |
( |
:им1[х |
й r,, |
рг,", |
ш1, |
. |
им, т: |
( :им1[х d ж й |
|
|
|
ш,1 |
d й ,т |
р, |
|
|
о ,V |
||
|
", |
рг,", |
|
ш1 , |
ir, , d нго |
ртр, |
,V |
о , V |
||
|
ш1, |
Bрi d |
рг,", |
ш1 , |
|
а затем попытаетесь вызвать этот метод так, как поступали ранее в этой главе со строковым типом
цц |
:( |
:(ш |
р:, |
", |
t nп |
|
5,", |
ш1, , |
т |
1, ш Bрiр d ,им г,хш ,(р 'l ,( [ |
|||||||
|
-рх,ш(5 |
|
d шх R |
,г |
:им 5,", |
ш, 1 ж |
|
|
|
срим r,рOeх: |
|
,г:им,d: ,г, |
V |
|
|
то это не сработает. Обобщенные типы в С# 3 .0 являются инвариантными. Но в Visual Studio 20 1 О и более поздних версий этот код скомпилируется, по скольку дэаоое лосе(лНn является ковариантным: более поздний порожденный тип можно использовать в качестве замены для типа более высокого порядка. С следующем разделе вы увидите конкретный пример.
удизотытобтизидьзйе
Приложение планирования может иметь события эrеавinкоторые содержат дату, и набор подклассов, одним из которых является сдол не.nсдолнеnN это эrеав.nКурсы знают количество своих студентов. Одним из этих их методов является dо песоiеаgо мъn
т |
r:( р:, |
"шm,сшr,им,ш х d_,им |
,хш ,(, |
,им |
[ 5,, им, |
, |
|
|
-рх,ш(5 |
d , ,им : |
,г :им |
5,, ,им |
, |
|
|
|
g |
|
,г:им, л : ,г Oe5, им> |
т>Bр6 |
х:им1 d ,ж V |
|
|
|
сримрr, йeх: |
|
еoздз, а, oьсь. коос ежы, oo.,

222 ЧАСТЬ 1 Основы программирования на С#