Г. Шилдт - С#4.0 Полное руководство (1160795), страница 132
Текст из файла (страница 132)
Не следует, однако, забывать, что первым параметром метода расширения является автоматически передаваемый объект, для которого вызывается этот метод: Как правило, метод расширения становится открытым членом своего класса. Глава 19. П((((( 679 В приведенном ниже примере программы создаются три простых метода расщирения. О Создать и использовать ряд методов расширения. пя1пе Яуятев; пя1пд Яуягев.61оЬа11гаг1оп; ятаттс с1аяя МуЕхГМеГЛя ( // Возвратить обратную величину числового значения типа бопЬ1е. роЫтс ятат1с бооЫе Вестргоса1(тЛ1я бооЫе ч) ( гетогп 1.0 / и; ) // Изменить на обратный регистр букв в символьной // строке и возвратить результат.
роЫтс ясаттс ятт1пВ ВенСаяе(ГЛтя ятг1по ятг) ( ятт1пд гавр = ""; ТотеасЛ(сЛаг сЛ 1п агт) ( тс(СЛаг.1я1оиег(сю ) Гевр += СЛаг.тооррет(сЛ, Си1тпте1пто. СоггепГСо1соге); е1яе Гевр += СЛаг.то'оиет(сЛ, Си1спте1пто.снгтептсо1тпге); ) теготп тевр; ) Возвратить абсолютное значение выражения и / б. роЫтс ятат1с допЫе АЬяогнтдеву(ГЛ1я бооЫе и, боиЫе б) ( гетитп МаГЛ.АЬя(п / с1); ) с1аяя Ехтоево ( ятат1с чотб Матп() ( боиЫе на1 = 8.0; ягт1пс ятт шя1рЛа Вета оашва"; // Вызвать метод расширения Вестргоса1()..
Сопяо1е.нг1теьтпе("Обратнан величина (О) равна (1)" ча1, на1.рес1ртоса1())( // Вызвать метод расширения ВечСаяе(). Сопяо1е.нт1теЬТпе(ясг + " после смены регистра: ятг.ненСаяе()); О Использовать метод расширения АЬябтнгбеву(!. Сопяа1е.нт1теьяпе("Результат вызова метода на1.ВЬяотн1с)еву(-2): на1.ВЬя01чгбеву(-2)); Эта программа дает следующий результат.
680 Часть!. Язык С() Обратная величина 8 равна 0.125 А1рла ВеТа Свеев после смены регистра: вЬРНА ЬВТА ЧАИИА Результат вызова метода ча1.АЬв01ч1беву(-2): Л В данном примере программы каждый метод расширения содержится в статическом классе МунхТНВТЬв. Как пояснялось выше, метод расширения должен быть объявлен в статическом классе. Более того, этот класс должен находиться в области действия своих методов расширения, чтобы ими можно было пользоваться. (Именно поэтому в исходный текст программы следует включить пространство имен Вувсев.
Ь1псь так как это дает возможность пользоваться методами расширения, связанными с П)ЧОВ Объявленные методы расширения вызываются для объекта таким же образом, как и методы экземпляра. Главное отличие заключается в том, что вызывающий объект передается первому параметру метода расширения. Поэтому при выполнении выражения ча1.АЬвотнгбеВУ(-2) объект ча1 передается параметру и метода расширения АЬвО1чз беВу ( ), а значение -2 — параметру б. Любопытно, что методы расширения несургоса1 () и АЬВР1чубену() могут вполне законно вызываться и для литерала типа г(ООЬ1е, как показаио ниже, поскольку они определены для этого типа данных.
8.0.кесгргоса1() 8.0.АЬвогчьбеВу(-1) Кроме того, метод расширения йечСаве () может быль вызван следующим образом. "АЬСОе".НечСаве 0 В данном случае возвращается строковый литерал с измененным на обратный регистром букв. ~ииЕ В версии .)Х)ЕТ Ргатетуог)с 4.0 внедрено новое дополнение Е1)Щ под названием РЕ1)ь)О. Это средство предназначено для поддержки параллельного программирования. Оно позволяет автоматически задействовать в запросе несколько доступных процессоров.
Подробнее о Р(.1)Щ и других средствах, связанных с параллельным программированием, речь пойдет в главе 24. 682 Часть Е Язык СЕ управления и ограничениям, что и управляемый код, и называется он небезопасным потому, что нельзя никак проверить, не выполняет ли он какое-нибудь опасное действие. Следовательно, термин небезопасный совсем не означает, что коду присущи какие-то изъяны. Это просто означает, что код может выполнять действия, которые не подлежат контролю в управляемой среде. Если небезопасный код может вызвать осложнения, то зачем вообще создавать такой код? Дело в том, что управляемый код не позволяет использовать указатели.
Если у вас имеется некоторый опыт программирования на С или С+т, то вам должно быть известно, что указатели представляют собой переменные, предназначенные для хранения адресов других объектов, т.е. они в какой-то степени похожи на ссылки в Св. Главное отличие указателя заключается в том, что он может указывать на любую область памяти, тогда как ссылка всегда указывает на объект своего типа. Но поскольку указатель способен указывать практически на любую область памяти, то существует большая вероятность его неправильного использования. Кроме того, используя указатели, легко допусгить программные ошибки. Именно поэтому указатели не поддерживаются при создании управляемого кода в Св.
А поскольку указатели все-таки полезны и необходимы для некоторых видов программирования (например, утилит системного уровня), в СФ разрешается создавать и использовать их. Но при этом все операции с указателями должны быть помечены как небезопасные, потому что они выполняются вне управляемой среды. В языке Св указатели объявляются и используются таким же образом, как и в С/С+в. Если вы знаете, как пользоваться ими в С/С.н; то вам нетрудно будет сделать это и в СК Но не забывайте, что главное назначение СФ вЂ” создание управляемого кода. А способность этого языка программирования поддерживать неуправляемый код следует использовать для решения лишь особого рода задач. Это, скорее, исключение, чем правило для программирования на Св. По существу, для компилирования неуправляемого кода следует использовать параметр компилятора /ппзаге.
Указатели составляют основу небезопасного кода, поэтому мы начнем его рассмотрение именно с них. Основы применения указателей Указатель представляет собой переменную, хранящую адрес какого-нибудь другого объекта, например другой переменной. Так, если в переменной х хранится адрес переменной у, то говорят, что переменная х указывает на переменную у. Когда указатель указывает на переменную, то значение этой переменной может быть получено или изменено по указателю. Такие операции с указателями называют ненрямои адресаяией. Объявление указателя Переменные-указатели должны быть объявлены как таковые. Ниже приведена общая форма объявления переменной-указателя: тип* имв переменной; где тип обозначает соонгносимый агин, который не должен быть ссылочным.
Это означает, что в Св нельзя объявить указатель на объект определенного класса. Соотносимый тип указателя иногда еще называют базовым. Обратите внимание на положение знака * в объявлении указателя. Он должен следовать после наименования типа. А имя переменной обозначает конкретное имя указателя-переменной. !лава 20. Небезопасный код, указатели, обиулявмыв типы и разные ключевые слова 683 Обратимся к конкретному примеру. Для того чтобы сделать переменную зр указателем на значение типа 1пс, необходимо объявить ее следующим образом.
1пг* ьрг А указатель. типа !!оас обълвляется так, как показано ниже. г! с* грг Вообще говоря, если в операторе объявления после имени типа следует знак *, то это означает, что создается переменнал типа указателя. Тип данных, на которые будет указывать сам указатель, зависит от его соотносимого типа. Поэтому в приведенных выше примерах переменная ьр может служить для указания на значение типа 1пс, а переменная 1р — для указания на значение типа 1!оас. Следует, однако, иметь в виду, что указателю ничто не мешает указывать.на что угодно.
Именно поэтому указатели потенциально небезопасны. Если у вас есть опыт программирования на С/С.н., то вы должны ясно понимать главное отличие в объявлении указателей в СФ и С/С++. При объявлении указателя в С/С.н- знак * не разделяет список псрсменных в объявлении. Поэтому в следующей строке кода: ьпс* р, с!г объявляетсл указатель р типа 1пг и переменная с! типа 1пе.
Это равнозначно двум следующим объявлениям. 1пг* р; ьпг сн А в СФ знак * является разделительным, и поэтому в объявлении ьпс* р, сг; создаются две переменные-указателя. Это равнозначно двум следующим объявлениям. 1пс* р! 1пс* сг; Это главное отличие следует иметь в виду при переносе кода С/С-н- на СФ. Операторы * и й в указателях В указателях применяются два оператора: * и ь.
Оператор л является унарным и возвращает адрес памяти своего операнда. (Напомним, что для унарного оператора требуется единственный операнд.) Например, в следующем фрагменте кода: ьпг* гр; 1пс пав = !Ог 1р = Ьппл; в переменной 1р сохраняется адрес памяти переменной ппвь Это адрес расположения переменной ппв в оперативной памяти компьк>гера. Он не имеет никакого отношения к значению переменной пшю Поэтому в переменной лр содержится не значение 1О, являющееся исходным для переменной пппь а конкретный адрес, по которому эта переменная хранится в оперативной памяти. Операцию л можно рассматривать как возврат адреса той переменной, перед которой она указывается.