Главная » Просмотр файлов » Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010)

Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865), страница 80

Файл №1160865 Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (Нэш Трей - C# 2010. Ускоренный курс для профессионалов (2010)) 80 страницаНэш Трей - C# 2010. Ускоренный курс для профессионалов (2010) (1160865) страница 802019-09-19СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 80)

Теперь рассмотрим, какой эффект даст небольшое изменение в методе С ге аге Ре 1еоз Се я. Если переместить объявление зогпеЧаг1аЬ1е в цикл, создающий массив делегатов, то на каждом шаге цикла будет создаваться новый экземпляр локальной переменной, эмулируя семантику распределения переменных в стеке. Обратите внимание на следующее изменение в методе СгеагеРе1ечагеж рпЬ11с ягагьс РгапСАпб1псгеаепС[) Сгеагеое1еоагея() РггпСАпб1псгевепС[] бе1еоагея = пен Рг1пСАпб1псгепепС[3] сог( гпС 1 = Ог г < Зг ++1 ) 1пе возмткаг1аЬ1а 0( бе1едагея[1] = бе1едаге ( СОПЯО1Е.ИГ1СЕ11ПЕ( ВОВЕЧатсаЬ|ЕВВ ) 1 ~1 ) гегпгп бе1едагеяг ) На этот раз вывод будет таким: Вот почему нужно соблюдать осторожность при использовании захвата переменных анонимными методами.

В первом случае три делегата захватывают одну и ту же переменную. Во втором случае они захватывают отдельные экземпляры этой переменной, поскольку каждая итерация цикла Рог создает новый [отдельный) экземпляр нокера та аЬ1 е. Данное мощное средство имеет смысл включить в свой инструментарий, но необхо)пкмс четко представлять, что при этом делается, чтобы не возникало проблем. Сообразительные читатели могут недоумевать, как может успешно работать такой код, если захватываемые переменные в этом примере относятся к типу значений, которые по умолчанию находятся в стеке.

Вспомните, что типы значений создаются в 302 Глава (О стеке, только если они не являются полями ссылочного типа, экземпляры которого создаются в куче, что включает случай. когда онн упаковываются. С другой стороны, зовеуаг1вЬ1е является локальной переменной, поэтому при нормальных условиях она создается в стеке. Но здесь мы имеем дело с ненормальной ситуацией. Ясно, что для экземпляра анонимного метода невозможно захватить локальную переменную из стека и рассчитывать, что она останется там, когда методу понадобится к ней обратиться.

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

Когда компилятор встречает захваченную локальную переменную типа значений, он "за кулисами" создает класс. Когда код инициализирует локальную переменную, компи- лятор генерирует код [Ь. создающий экземпляр этого прозрачного класса и инициали- зирующий его поле, которое в данном случае представляет зотеуагьаЬ1е. В этом легко удостовериться, открыв скомпилированный код первого примера в !ЬРАЭМ или йейестог. В код была включена дополнительная переменная апогсегувгьа]>1е, чтобы можно было видеть отличие в том, кзк они представлены в ]Ь.

Поскольку апогсегуагьаЬ1е не захватывается, она создается в стеке, как и можно было ожидать. Ниже показана часть кода!Ь для Сгеасере1еоагез после компиляции примера с включенной отладоч- ной информацией. // Созе зьзе 85 (Ох55] .вахзгвск 5 .1оса1з ьп1С ([0) с1азз Рг1пгяп<(1псгетепг() <(е1еоасез, [1) Ьпс32 апоеквхтаг1в]41в, [2) ьпс32 1, [3) с1азз РгьпСАпп1псгетепг '<>9 Саснеслпопутоизиегнопое1еоаге1', [4) с1азз Епггугоьпг/'<>с оьзр1ауС1ззз2' '<>8 1осаьзЗ', [5) с1азз РгьпСАпс1псгеаепг[) С58180000, [6) ]>оо1 С88480001] 1Ь ОООО: 1ппп11 1Ь 0001: вг1ос.З 1ь 0002: пеиоьб зпаеапсв чоьт( епекувоьпе/'<>с ртврьвус1авв2'::.сеог() 1Ь 0007: зг1ос.з '<>8 1оса1зЗ' 1Ь 0009: пор 1Ь Оооа: 1ос.т4.3 1Ь 000]>: пенагг Рг1пСАпп1псгевепг 1Ь 0010: зг1ос.о 1Ь 0011: 1о1ос.з '<>8 1оса1зЗ' 11, 0013: 1с(с.14.0 1Ь 0014: вс816 1пс32 Епсгуво1пс/'<>о Равр1ауС1авв2':."вовечагааь1е 1Ь 0019: 1сс.14.1 1Ь 001а: зг1ос.1 1Ь 001Ь: 1г(1ос.1 1Ь 001с: са11 томб [взсог11Ь]зузсет.Сспзо1е::ИгьсеЬгпе(1пс32) Обратите внимание на то, как используются упомянутые выше две переменных.

В строке 11. 0 002 создается новый экземпляр скрытого класса. В данном случае ком- пилятор назвал этот класс <>с Оьзр1ауС1азз2. Этот класс содержит общедоступное Делегаты, анонимные функции и события 303 поле экземпляра по имени вогяетгэгсэЫе, значение которому присваивается в строке 11, 0014.

Компилятор прозрачно вставил тот самый пресловутый промежуточный уровень в форме класса, чтобы решить проблему захвата локальной переменной анонимными методами. К тому же отметьте тот факт, что впоспегчагбаь1е трактуется как нормальная локальная переменная, находящаяся в стеке, на что указывает ее объявление в разделе локальных переменных метода.

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

Те из вас, кто программировал на С++ и пользовался библиотеками БТ1. или Вопят 1ЛЬгагу, должны быть знакомы с привязками параметров. Ниже приведен соответствующий пример. пвгпд яуягеэ) рпыгс бе1едвсе гпс Орегэсбоп( гпс х, гпс у )) рпЬ11с с1ввя Вапб2пб ( рпЫгс бе1едэсе 1пС ВоппбОе1едасе( гпг х )т рпЫгс Вгпб2пб( ОрегаС1оп бе1, 1пг агд2 ] ( спгя.бе1 = бе1; спгя.агд2 = агд2т ) рпЬ11с ВоппбОе1едаге Вгпбег ( дес ( гегпгп бе1едвге( гпг вгд1 ) ( геспгп бе1( вгд1, агд2 ); )т ) ) рггчвге Орегаг1оп бе1) рггчасе 1пг агд2; рпЫгс с1авв ЕпггуРогпг ( вгаггс гпг йбб( гпг х, гпг у ) ( гегпгп х + у; вгаггс чо1б Мэгп() ( Вгпб2пб Ькпбег пен Вгпб2пб( пен Орегаггоп(хпггуРоспг.йбб), 4 )г Сопво1е.нгтгесгпе( Ьгпбег.Вгпбег(2) )г Подробнее о каррироввнии речь пойдет в главе 15, где рассматриваются лямбда-выражения, предлагающие более выразительный способ достижения тех же целей, которым служат анонимные методы.

304 Глава 10 В этом примере делегат типа Оре гас 1 оп с двумя параметрами, который выполняет обратный вызов статического метода Епс гуро1п Г . Абб, преобразуется в делегат, принимающий только один параметр. Второй параметр фиксируется с помощью класса вбпб2сн). По сути, поле экземпляра Вбпб2пб.

агд2 устанавливается в значение, которое должно быть зафиксировано за вторым параметром. Затем свойство В).пб2пб. В1пбег возвращает новый делегат в форме экземшшра анонимного метода, который захватывает поле экземпляра и применяет его вместе с первым параметром, переданным в точке вызова. Читатели, знакомые с С++ и ЗТ)., возможно, возразят, что этот пример был бы намного более полезен, если бы Вбгсс)2пс( был обобщенным типом, чтобы поддерживать обобщенный делегат с двумя параметрами — подобно тому, как это делается в БТ(..

И на самом деле, это было бы хорошо; однако некоторые языковые барьеры вызывают определенные затруднения. Начнем с попытки сделать обобщенным тип делегата в классе Ввгсс)2гк). Можно попробовать написать следующий код: // НЕ КОМПИЛИРУЕТСЯ!!! рпЫбс с1вяв В1пб2пб< Ое1едасеТуре > ( рпЫ1о бе1едвге Тпс ВоппоОе1едасе ( 1пг х ) с рпЬ11с Вгпб2пб( Ое1едвсеТуре бе1, 1пс вгд2 ) ( Гпгв.бе1 = бе1; ЬЫя.агд2 = ягд2; ) риЬ11с Воипббе1едасе Вгпбег ( дег ( геспгп бе1едвсе( 1пс вгд1 ) ( гевал ГЫв.бе1( агд1, агд2 ); // Овибка! )' ) ) рггтяге Ое1едасеТуре бе11 рггтвге Тпс згд2; Эго благородная попытка, но, к сожалению, неудачная, поскольку компилятор оказывается в недоумении внутри тела анонимного метода и жалуется на то, что поле экземпляра используется подобно методу. Ошибка, которую он выдаст, выглядит следующим образом: еггог СБ1955: Ноп-ТптосаЬ1е ветпег 'В1пб2пб<Ое1едасеТуре>.бе1' сапное Ье пвеб 112е а веспоб овибка С51955с Невызываемый член В1пб2пб<Ое1едагегуре>.бе1 не может быть использован подобно методу Компилятор полностью прав.

Сделать подобное однозначно не удастся. Как тогда должен поступить программист7 Другая попытка связана с применением ограничений обобщений. Используя ограничения, можно сказать, что невзирая на то, что тип является обобщенным, он должен наследоваться от определенного базового класса или реализовывать определенный интерфейс. Отлично! Давайте поможем компилятору и сообщим, что Ое1едасеТуре наследуется от Бувселс. Ое1едасе, как показано ниже: // ПО-ПРЕЖНЕМУ НЕ КОМПИЛИРУЕТСЯ!!! рпЫТс с1аяз Вгпб2пб< Ое1едвсеТуре > ыпеге Ое1едасеТуре: Ое1едасе ( рпЬ11с бе1едасе Тпс Воппббе1едзсе( 1пг х ) Делегаты, анонимные функции и события 305 рпЪ1тс Втпб2пб( Ре1едатетуре бе1, тпт агд2 ) ( ЬЬ1з.бе1 = бе17 тнтз.агд2 = агд27 ) рпЬ11с ВоспбРе1едате Втпбег ( дет ( гетпгп бе1едате( тпт агд1 ) ( гетигп тЬТя.бе1( агд1, агд2 )) /У Ошибка! ): ) ) рг1часе Ре1едатеТуре бе17 ргъчате тпт атд2; ) К сожалению, опять неудача! На этот раз компилятор сообщает, что ограничение на типе Ре1едате не разрешено, выдавая следующую ошибку: еггог СЯ0702: Сопятгатпт саппот Ье яреста1 с1аяя 'Яуятеш.ое1едаге' ошибка СЯ0702т Ограничение не может быть специальным классом Яуягеш.ое1едате Это приводит к решению использовать для выполнения работы обобщенные делегаты.

Решение задачи выглядит следующим образом: пятпд Яуятеш) рпь11с с1азз Втпб2пб<Атд1туре, Агд2туре, кессгптуре> ( рпЬ11с Втпб2пб( Рспс<лгд)туре, Агд2туре, Кетпгптуре> бе1, Агд2Туре агд2 ) ( свез.бе1 = бе17 тйъз.агд2 = агд2; ) роЬ11с Рппс<лгд1Туре, КегагпТуре> Втпбет ( дет ( гетега бе1едате( Агд1Туре агд1 ) ( гетпгп бе1( агд1, агд2 )) ) ) ргтчаге Рппс<Агд1туре, Агд2туре, кегптптуре> бе17 ргтчате Агд2Туре агд27 ) рпЬ11с с1аяз ЕптгуРо1пт. ( зтаттс тпт Абб( тпт х, 1пт у ) ( гетпгп х е ут ) ятат1с чогб Матп() ( В1пб2пб<1пг,тпт,тпг> Ьепбег = пен В1пб2пб<1пт,апт,тпт>( ЕптгуРотпт.лбб, 4 )т Сспяо1е.кг1те11пе( Ьгпбег.ВТпбег(2) )) ) ) Для того чтобы анонимный метод мог использовать поле с(е1 как метод, компилятор должен знать, что зто делегат. Оно не может просто относиться к типу яузсеш. Ре1едате. Чтобы вызвать зто поле через делегат с использованием синтаксиса вызова метода, оно должно иметь конкретный тип делегата.

Характеристики

Тип файла
DJVU-файл
Размер
8,22 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Нэш Трей - C# 2010
Accelerated_C_2010-4565
3_syntax_overview
3_generics_1.cs
as_1.cs
boxing.cs
conversions_1.cs
implicit_type_1.cs
is_1.cs
references_1.cs
references_2.cs
references_3.cs
values_1.cs
4_classes_structs
4_abstract_classes_1.cs
4_beforefieldinit_1.cs
4_box_1.cs
4_box_2.cs
4_box_3.cs
4_box_4.cs
4_box_5.cs
4_class_definition_1.cs
4_compareto_1.cs
4_containment_example_1.cs
4_containment_example_2.cs
4_containment_example_3.cs
4_ctor_struct_1.cs
4_ctor_struct_2.cs
4_ctor_struct_3.cs
4_destructor_1.cs
4_destructor_2.cs
Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7030
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее