Главная страница
Навигация по странице:

  • Задания для самостоятельной работы

  • Знакомство с делегатами

  • Васильев А.Н. Основы программирования на C#. Васильев А. Н. Программирование


    Скачать 5.54 Mb.
    НазваниеВасильев А. Н. Программирование
    АнкорВасильев А.Н. Основы программирования на C
    Дата20.09.2022
    Размер5.54 Mb.
    Формат файлаpdf
    Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
    ТипДокументы
    #686596
    страница5 из 40
    1   2   3   4   5   6   7   8   9   ...   40
    55
    не используются. Все, что описано в интерфейсе, имеет уровень доступа Класс может реализовать один или несколько интерфейсов. Интерфейсы, реализуемые в классе, указываются в описании класса после его имени (через двоеточие. Названия интерфейсов разделяются запятыми. Если при этом класс еще и наследует базовый класс, топе- ред списком реализуемых интерфейсов указывается имя базового класса Если класс реализует интерфейс, тов классе должны быть описаны все методы, свойства и индексаторы, объявленные в интерфейсе. Соответствующие члены класса описываются с ключевыми словами public и override
    • На основе интерфейса нельзя создать объектно можно объявить переменную интерфейсного типа. Интерфейсная переменная может ссылаться на объект любого класса, реализующего данный интерфейс. Доступ через такую переменную возможен только к тем членам объекта, которые объявлены в интерфейсе Для методов, свойств и индексаторов из интерфейса в классе, реализующем интерфейс, можно выполнять явную реализацию. Соответствующий член класса описывается без ключевого слова public
    , а перед его названием через точку указывается имя интерфейса. Доступ к такому члену можно получить через интерфейсную переменную соответствующего интерфейса.
    Задания для самостоятельной работы
    Дядя Степан, помог бы ты им, а Ну грех смеяться над убогими.
    из к/ф Формула любви Напишите программу, содержащую абстрактный базовый класс с защищенным полем, являющимся ссылкой на целочисленный массив. У класса должен быть конструктор с одним аргументом (определяет размер массива и создает его, целочисленное свойство (значение — размер массива, абстрактный метод (без аргументов, не возвращает результат) и индексатор с целочисленным индексом (доступен для чтения
    Глава и записи. В производном классе описать абстрактный метод из базового класса, чтобы он отображал в консоли содержимое массива. Индексатор определить так, чтобы сего помощью можно было прочитать значение элемента массива и присвоить значение элементу массива Напишите программу, содержащую базовый класс с защищенным текстовым полем. У класса должен быть конструктор с текстовым аргументом, доступное для чтения абстрактное целочисленное свойство, доступный для чтения абстрактный индексатор с целочисленным индексом, не возвращающий результат абстрактный метод с текстовым аргументом, не возвращающий результат абстрактный метод без аргументов. В производном классе свойство результатом возвращает количество символов в текстовом поле, значением выражения с проиндексированным объектом является код символа в тексте, метод с текстовым аргументом присваивает новое значение полю, а метод без аргументов отображает значение поля в консольном окне Напишите программу, в которой будет описан интерфейс с методом без аргументов, который возвращает результатом целое число. На основе интерфейса создайте два класса. У каждого класса должно быть целочисленное поле. В первом классе метод результатом возвращает сумму четных чисел, во втором классе метод возвращает результатом сумму нечетных чисел. Количество слагаемых в сумме определяется полем объекта, из которого вызывается метод. Проверьте работу метода, получив доступ к объекту класса через объектную переменную и через интерфейсную переменную Напишите программу, содержащую абстрактный класс с двумя защищенными целочисленными полями и конструктор с двумя целочисленными аргументами. В классе должен быть объявлен абстрактный ин- дексатор с целочисленным индексом. Опишите интерфейс, в котором есть метод с целочисленным аргументом и целочисленным результатом. Опишите класс, который наследует абстрактный базовый класс и реализует интерфейс. В этом классе опишите индексатор так, чтобы при четном индексе выполнялось обращение к первому полю, а при нечетном индексе обращение выполнялось ко второму полю. Метод следует описать таким образом, чтобы он результатом возвращал сумму значений полей, умноженную на аргумент метода Напишите программу, содержащую два интерфейса. В первом интерфейсе опишите метод с символьным аргументом и целочисленным результатом, а во втором интерфейсе — метод с целочисленным
    Абстрактные классы и интерфейсы
    57
    аргументом и символьным результатом. Опишите класс, реализующий оба интерфейса. Проверьте работу методов, вызвав их через объектную переменную и через интерфейсные переменные (там, где это возможно Напишите программу, в которой на основе двух интерфейсов создается класс. Водном интерфейсе объявлен индексатор с символьным индексом, возвращающий целочисленное значение. В другом интерфейсе объявлен индексатор с целочисленным индексом, возвращающий символьное значение Напишите программу, в которой класс создается на основе двух интерфейсов. В первом интерфейсе есть целочисленное свойство, доступное для чтения и записи. Во втором индексаторе есть текстовое свойство, доступное для чтения и записи. В каждом из интерфейсов объявлены одинаковые (с одинаковыми именами) методы, без аргументов, не возвращающие результат. В классе описать соответствующий метод, который в консольном окне отображает значения свойств Напишите программу, в которой класс создается на основе двух интерфейсов. В каждом из интерфейсов объявлено текстовое свойство с одними тем же названием, доступное только для чтения. В классе выполнить общую (неявную) реализацию свойства, а также явную специализацию свойства для каждого из интерфейсов. Проверьте значение свойства для объекта класса, выполнив ссылку на объект через объектную переменную и интерфейсные переменные Напишите программу, в которой класс создается на основе абстрактного базового класса и интерфейса. В абстрактном классе есть поле, являющееся ссылкой на защищенный символьный массив. Конструктору класса передается текстовый аргумент, на основе которого создается и заполняется символьный массив. В абстрактном классе опишите метод, который по целочисленному аргументу возвращает значение символа с соответствующим индексом в массиве. Также в абстрактном классе должен быть объявлен абстрактный метод с двумя аргументами целое число и символ, не возвращающий результат. В интерфейсе должен быть объявлен метод с таким же именем, нос одним текстовым аргументом. Также в интерфейсе должен быть объявлен индексатор (с двумя аксессорами) с символьным результатом и целочисленным индексом. На основе абстрактного класса и интерфейса нужно создать класс. Абстрактный метод из базового класса переопределить таким образом, чтобы он присваивал значение элементу массива, метод из интерфейса
    Глава должен создавать новый массива индексатор должен предоставлять доступ к элементам массива Напишите программу, содержащую абстрактный класс и два интерфейса. Класс должен содержать объявление абстрактного свойства с двумя аксессорами), абстрактного индексатора (с двумя аксессорами) и абстрактного метода. Такое же свойство, индексатор и метод должны быть в интерфейсах. На основе абстрактного класса и интерфейсов необходимо создать класс. В этом классе необходимо выполнить явную реализацию для свойства, индексатора и метода для каждого из интерфейсов. Проверьте работу свойства, индексатора и метода, получив доступ к объекту класса через объектную переменную и через интерфейсные переменные
    Глава ДЕЛЕГАТЫ И СОБЫТИЯ
    Я красавец. Быть может, неизвестный собачий принц. Инкогнито.
    из к/ф Собачье сердце»
    В этой главе обсуждаются достаточно важные и не совсем обычные темы. Наш ближайший план в изучении языка C# включает такие пункты знакомство с делегатами ссылки на методы и создание экземпляров делегата анонимные методы лямбда-выражения;
    • знакомство с событиями.
    Мы также коснемся других тем, которые связаны с использованием делегатов и событий. Следует отметить, что вопросы, рассматриваемые далее, относятся к фундаментальным технологиям, используемым в том числе и при разработке приложений с графическим интерфейсом.
    Знакомство с делегатами
    Мы к вам, профессор, и вот по какому делу.
    из к/ф Собачье сердце»
    Ранее мы рассматривали различные классы, на основе которых создавались объекты. Мы явно или неявно исходили из того, что класс представляет собой некоторый аналог типа данных, с поправкой на то обстоятельство, что в классе спрятаны не только данные (или средства для их реализации, но и некоторая функциональность в виде кода для обработки этих данных. Теперь нам предстоит познакомиться с еще
    Глава более специфическим типом — речь идет о делегатах. Чтобы понять, что же такое делегат, удобно представлять делегат как некий аналог класса. Также как на основе класса создается объект, на основе делегата тоже создается объект. Мы будем называть такой объект экземпляром делегата. Экземпляр делегата — это такой специфический объект, который может ссылаться на методы НАЗ А МЕТКУ Существует определенная неоднозначность, связанная с терминологией. Иногда делегатом называют и собственно делегат, и экземпляр делегата. Здесь нет ничего страшного — главное, чтобы это не приводило к недоразумениям. Иногда делегат называют типом делегата. Мы будем придерживаться принципа, согласно которому на основе делегата создается экземпляр делегата, подобно тому как на основе класса создается объект (экземпляр класса).
    Правда мы еще не знаем, что такое ссылка на метод. Нов этом случае можно отталкиваться от позитивистской концепции есть некий объект (экземпляр делегата, который связан с некоторым методом объект знает, что это за метод и где его искать. Объект можно вызывать, как метод. При вызове объекта на самом деле вызывается метод, с которым связан объект НАЗ А МЕТКУ Вообще, здесь ничего удивительного нет. Переменная массива ссылается на массив. Объектная переменная ссылается на объект. Когда мы обращаемся к переменной массива, получаем доступ к массиву. Когда обращаемся к объектной переменной, получаем доступ к объекту. Экземпляр делегата ссылается на метод. Когда мы обращаемся к экземпляру делегата, то получаем доступ к методу. Просто для метода получение доступа означает, что метод вызывается.
    Как же описывается делегат и как на его основе создавать экземпляры и, самое главное, что сними потом делать Начнем с описания делегата. Чтобы понять логику того, как описывается делегат, следует еще раз вспомнить, зачем он нужен. Нужен делегат для создания объектов, которые будут ссылаться на методы. А что важно при работе с методом Какие параметры или характеристики могут использоваться для классификации методов Несложно сообразить, что это тип результата и количество и тип аргументов. Поэтому когда мы описываем делегат,
    Делегаты и события
    61
    то должны явно указать, на какие методы смогут ссылаться экземпляры делегата. Другими словами, нам необходимо указать, какого типа результат и какого типа аргументы должны быть у метода, чтобы экземпляр данного делегата мог ссылаться на метод НАЗ А МЕТКУ Вообще стоит заметить, что тип аргументов в методе может быть базовым для типа аргументов в делегате. Также разрешается, чтобы тип результата в делегате был базовым для типа результата метода.
    Именно эти характеристики указываются при описании делегата. Начинается оно с ключевого слова delegate. Далее указывается идентификатор типа — это идентификатор типа результата метода, на который сможет ссылаться экземпляр делегата. Например, если указано ключевое слово int, то это означает, что экземпляр делегата сможет ссылаться на методы, которые результатом возвращают значение. Далее, после идентификатора типа указывается название делегата. Это имя, которое мы даем делегату, сродни имени класса. После имени делегата в круглых скобках описываются аргументы (указывается тип и формальное название аргумента. Это аргументы, которые должны быть у метода для того, чтобы ссылку на метод можно было присвоить экземпляру делегата. Общий шаблон объявления делегата такой
    ɬɢɩ Фактически, если взять сигнатуру (тип результата, имя и список аргументов) метода, на который может ссылаться экземпляр делегата, заменить в сигнатуре название метода на название делегата и указать в самом начале ключевое слово delegate, мы получим объявление делегата. Например, мы хотим описать делегат с названием MyDelegate, экземпляру которого можно было бы присвоить ссылку на метод. У метода два аргумента (типа int и string) и результат типа char. Такой делегат объявлялся бы следующей инструкцией char MyDelegate(int k,string Это объявление делегата. Но делегат, напомним, нужен для того, чтобы создать объект (экземпляр делегата. Схема здесь достаточно простая, и внешне все напоминает создание объекта класса, где роль класса играет делегат. Мы можем использовать следующий шаблон ɩɟɪɟɦɟɧɧɚɹ=new ɞɟɥɟɝɚɬ(ɦɟɬɨɞ);
    Глава В данном случае инструкцией вида new
    ɞɟɥɟɝɚɬ(ɦɟɬɨɞ) создается экземпляра ссылка на этот экземпляр записывается в ɩɟɪɟ-
    ɦɟɧɧɭɸ. Экземпляр делегата, на который ссылается ɩɟɪɟɦɟɧɧɚɹ, сам ссылается на
    ɦɟɬɨɞ, указанный в инструкции new ɞɟɥɟɝɚɬ(ɦɟɬɨɞ).
    q
    ПОДРОБНОСТИ bВообще, цепочка ссылок получается нетривиальная. Есть переменная (аналог объектной переменной, которая ссылается на экземпляр делегата (объект. Этот экземпляр делегата ссылается на метод.
    Возвращаясь к примеру с делегатом MyDelegate, мы могли бы создать экземпляр этого делегата командой такого вида meth=new Данной командой объявляется объектная переменная meth типа
    MyDelegate
    (фактически объектная переменная, в эту переменную записывается ссылка на созданный объект (экземпляр делегата
    MyDelegate
    ), асам этот объект ссылается на метод, указанный вкруг- лых скобках в инструкции new MyDelegate(
    ɦɟɬɨɞ). Осталось осветить вопрос стем, как выполняется ссылка на метод. Здесь все очень просто для выполнения ссылки на метод достаточно указать имя этого метода (без круглых скобок и аргументов. Если речь идет о выполнении ссылки на нестатический метод, то указывается имя объекта и название метода (разделенные точкой, то есть ссылка на нестатический метод выполняется в формате
    ɨɛɴɟɤɬ.ɦɟɬɨɞ. Если метод статический, то ссылка на него выполняется в формате
    ɤɥɚɫɫ.ɦɟɬɨɞ, то есть указывается имя класса и после него, через точку — имя метода. Например, если нужно выполнить ссылку на метод method(), который должен вызываться из объекта obj, то она будет выглядеть как obj.method. Команда создания экземпляра делегата, ссылающегося на метод method() объекта obj
    , выглядит так meth=new Если метод method() статический в классе MyClass, то ссылка на такой метод выполняется как MyClass.method. Команда создания экземпляра делегата, ссылающегося на статический метод method() класса
    MyClass
    , выглядит следующим образом meth=new MyDelegate(MyClass.obj);
    Делегаты и события
    63
    После того как мы создали экземпляр делегата, сего помощью можно вызывать метод, на который экземпляр ссылается. Для этого достаточно вызвать экземпляр делегата. Например, если экземпляр делегата meth ссылается на метод method() объекта obj и мы хотим вызвать этот метод с аргументами number (целое число типа int) и text значение типа string), то мы можем воспользоваться командой meth(number,text)
    , которая будет означать выполнение инструкции obj.method(number,text)
    . Если экземпляр делегата meth ссылается на статический метод method() класса MyClass, то для выполнения инструкции MyClass.method(number,text) можно воспользоваться командой meth(number,text).
    q
    ПОДРОБНОСТИ bВыше мы назвали переменную meth экземпляром делегата, что не совсем точно. Переменная meth ссылается на экземпляр делегата (который ссылается на метод. Обычно, если это не будет приводить к недоразумениям, мы будем отождествлять переменную, ссылающуюся на экземпляр делегата, с этим экземпляром делегата.
    Количество и тип аргументов, которые следует передать экземпляру делегата при вызове, определяются тем, как описан соответствующий делегат. Скажем, если делегат MyDelegate описан так, как указано выше, то экземпляр делегата MyDelegate следует вызывать с двумя аргументами целочисленными текстовым, — в соответствии стем, какие аргументы указаны после названия делегата MyDelegate в его объявлении.
    Описанный выше способ создания экземпляра делегата — не единственный и не самый простой. Можно пойти более радикальным путем объявить переменную, тип которой является делегатом, и присвоить такой переменной ссылку на метод. Шаблон команды следующий Вернемся к делегату MyDelegate и методу method(): для нестатиче- ского метода все могло бы выглядеть так Если метод статический, то экземпляр делегата можно создать таким образом Глава При присваивании ссылки на метод переменной типа делегата происходит следующее создается экземпляр делегата, который ссылается на данный метода ссылка на созданный экземпляр делегата присваивается переменной.
    Перейдем к практическим моментам. В листинге 2.1 представлена программа, в которой объявляются делегаты, создаются экземпляры делегатов и затем эти экземпляры делегатов используются для вызова методов Листинг 2.1. Знакомство с делегатами System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate char MyDelegate(int k,string txt);
    //
    Ʉɥɚɫɫ:
    class MyClass{
    //
    ɐɟɥɨɱɢɫɥɟɧɧɨɟ ɩɨɥɟ:
    public int code;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ:
    public MyClass(int n){
    code=n;
    }
    //
    ɇɟɫɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɫ ɞɜɭɦɹ ɚɪɝɭɦɟɧɬɚɦɢ:
    public char getChar(int k,string txt){
    return (char)(txt[k]+code);
    }
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɫ ɞɜɭɦɹ ɚɪɝɭɦɟɧɬɚɦɢ:
    public static char getFirst(int k,string txt){
    return txt[k];
    }
    }
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class DelegateDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɫ ɞɜɭɦɹ ɚɪɝɭɦɟɧɬɚɦɢ:
    static char getLast(int k,string txt){
    Делегаты и события return txt[txt.Length-k-1];
    }
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
    MyClass obj=new MyClass(5);
    //
    ɋɨɡɞɚɧɢɟ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    MyDelegate meth=new MyDelegate(obj.getChar);
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ \ƍ{0}\ƍƎ,meth(4,ƎAlphaƎ));
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɡɧɚɱɟɧɢɹ ɩɨɥɸ ɨɛɴɟɤɬɚ:
    obj.code=1;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ \'{0}\'Ǝ,meth(4,ƎAlphaƎ));
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɧɨɜɨɝɨ ɡɧɚɱɟɧɢɹ ɩɟɪɟɦɟɧɧɨɣ ɞɟɥɟɝɚɬɚ:
    meth=MyClass.getFirst;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ \ƍ{0}\ƍƎ,meth(2,ƎAlphaƎ));
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɧɨɜɨɝɨ ɡɧɚɱɟɧɢɹ ɩɟɪɟɦɟɧɧɨɣ ɞɟɥɟɝɚɬɚ:
    meth=getLast;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ \ƍ{0}\ƍƎ,meth(1,ƎAlphaƎ));
    Результат выполнения программы такой Результат выполнения программы (из листинга 2.1)

    ɋɢɦɜɨɥ 'f'
    ɋɢɦɜɨɥ 'b'
    ɋɢɦɜɨɥ 'p'
    ɋɢɦɜɨɥ 'h'
    Глава Делегат MyDelegate в программе объявляется инструкцией delegate char MyDelegate(int k,string txt). Такое объявление означает, что экземпляр делегата может ссылаться на метод, который результатом возвращает значение типа char и имеет два аргумента первый типа int и второй типа В программе описывается класс MyClass. В классе описано открытое целочисленное поле code и конструктор с одним аргументом (аргумент задает значение поля объекта. Еще в классе описано два метода неста- тический и статический. У каждого из них два аргумента (целое число и текст, и каждый из них возвращает результатом символьное значение. Оба метода соответствуют характеристикам делегата MyDelegate, и поэтому экземпляр делегата сможет ссылаться на эти методы.
    Нестатический метод getChar() имеет два аргумента k (целое число) и txt (текст. Результатом возвращается символ, вычисляемый выражением ПОДРОБНОСТИ bИз текста txt берется символ с индексом k
    (выражение txt[k]
    ), к коду полученного символа прибавляется значение поля code
    выражение, и полученное число преобразуется к текстовому формату (выражение
    (char)(txt[k]+code)
    ). Получается, что результатом является символ, смещенный к символу txt[k]
    на количество позиций, определяемое значением поля Статический метод getFirst() с целочисленным аргументом k и текстовым аргументом txt возвращает результатом символ из текста txt с индексом k (выражение В классе DelegateDemo, в котором описан главный метод Main(), есть описание еще одного статического метода getLast(). Метод для заданного текста txt (второй аргумент) возвращает символ из этого текста с индексом k (первый аргумент, если индекс отсчитывать с конца текста (результат вычисляется как В методе Main() командой MyClass obj=new MyClass(5) создается объект obj класса MyClass, значение поля code объекта obj равно Экземпляр делегата MyDelegate создается командой MyDelegate met h=new
    MyDelegate(obj.getChar). В итоге мы получаем переменную
    Делегаты и события делегата MyDelegate, которая ссылается на экземпляр делегата, ссылающийся на метод getChar() объекта obj. Поэтому при вызове экземпляра делегата инструкцией meth(4,
    ƎAlphaƎ) из объекта obj вызывается метод getChar() с аргументами 4 и
    ƎAlphaƎ. В результате из текста
    ƎAlphaƎ берется символ с индексом 4 (это символ ƍaƍ) ивы- полняется смещение на 5 позиций. В результате получаем символ Далее мы командой obj.code=1 меняем значение поля code объекта obj и снова вызываем экземпляр делегата с теми же аргументами команда. Теперь результатом является символ ƍbƍ, поскольку к символу
    ƍaƍ применяется смещение на 1 позицию (новое значение поля code), а не на 5 (старое значение поля code), как было ранее.
    Командой meth=MyClass.getFirst переменной meth делегата
    MyDelegate присваивается новое значение ссылка на статический метод) класса MyClass. После этого вызов экземпляра делегата командой meth(2,
    ƎAlphaƎ) означает вызов статического метода getFirst()
    с аргументами 2 и
    ƎAlphaƎ. Результатом является символ (символ с индексом 2 в тексте Командой meth=getLast экземпляру делегата meth в качестве значения присваивается ссылка на статический метод getLast(). Поскольку команда присваивания находится (в главном методе) в том же классе, в котором описан статический метод getLast(), то имя класса в ссылке на метод можно не указывать. При вызове экземпляра делегата командой) вызывается метод getLast() с аргументами 1 и
    ƎAlphaƎ. Результатом является символ ƍhƍ: второй индекс с конца текста Многократная адресация Так что передать мой король Передай твой король мой пламенный при- вет!
    из к/ф Иван Васильевич меняет профессию»
    Делегаты поддерживают многократную адресацию. Это означает, что экземпляр делегата может ссылаться не на один, а сразу на несколько методов. Если так, то при вызове делегата выполняется цепочка вызовов последовательно вызываются методы, на которые ссылается
    Глава вызываемый экземпляр делегата. Методы вызываются в той последовательности, в которой ссылки на методы добавлялись экземпляру делегата. Для добавления ссылки на метод экземпляру делегата используется оператор += (команда вида
    ɷɤɡɟɦɩɥɹɪ+=ɦɟɬɨɞ) или полная версия операции присваивания вида Таким образом, мы можем связать с экземпляром делегата не только отдельный метод, но и целый список методов. Если впоследствии нам понадобится удалить ссылку на метод из списка методов, на которые ссылается экземпляр делегата, можно воспользоваться оператором (команда вида
    ɷɤɡɟɦɩɥɹɪ-=ɦɟɬɨɞ) или командой вида
    ɷɤɡɟɦɩɥɹɪ=ɷɤɡɟɦɩɥɹɪ-ɦɟɬɨɞ. В листинге 2.2 представлена программа, в которой используется многократная адресация для экземпляра делегата Листинг 2.2. Многократная адресация для экземпляров делегата System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate void MyDelegate();
    //
    Ʉɥɚɫɫ:
    class MyClass{
    //
    Ɍɟɤɫɬɨɜɨɟ ɩɨɥɟ:
    public string name;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɬɟɤɫɬɨɜɵɦ ɚɪɝɭɦɟɧɬɨɦ:
    public MyClass(string txt){
    name=txt;
    }
    //
    Ɇɟɬɨɞ ɛɟɡ ɚɪɝɭɦɟɧɬɨɜ:
    public void show(){
    Console.WriteLine(name);
    }
    }
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class MulticastDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɛɟɡ ɚɪɝɭɦɟɧɬɨɜ:
    static void makeLine(){
    Делегаты и события Console.WriteLine(
    Ǝ--------Ǝ);
    }
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɨɜ:
    MyClass A=new MyClass(
    ƎɈɛɴɟɤɬ AƎ);
    MyClass B=new MyClass(
    ƎɈɛɴɟɤɬ BƎ);
    MyClass C=new MyClass(
    ƎɈɛɴɟɤɬ CƎ);
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɞɟɥɟɝɚɬɚ:
    MyDelegate meth;
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɞɟɥɟɝɚɬɚ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ:
    meth=A.show;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    meth();
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɞɟɥɟɝɚɬɚ ɧɨɜɨɝɨ ɡɧɚɱɟɧɢɹ:
    meth=makeLine;
    //
    Ⱦɨɛɚɜɥɟɧɢɟ ɦɟɬɨɞɨɜ ɜ ɫɩɢɫɨɤ ɜɵɡɨɜɚ:
    meth+=A.show;
    meth+=B.show;
    meth=meth+C.show;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    meth();
    //
    ɍɞɚɥɟɧɢɟ ɦɟɬɨɞɚ ɢɡ ɫɩɢɫɤɚ ɜɵɡɨɜɚ:
    meth-=B.show;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    meth();
    //
    ɍɞɚɥɟɧɢɟ ɦɟɬɨɞɚ ɢɡ ɫɩɢɫɤɚ ɜɵɡɨɜɚ:
    meth=meth-A.show;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    meth();
    }
    }
    Глава Результат выполнения программы следующий Результат выполнения программы (из листинга 2.2)
    Ɉɛɴɟɤɬ A
    --------
    Ɉɛɴɟɤɬ A
    Ɉɛɴɟɤɬ B
    Ɉɛɴɟɤɬ C
    --------
    Ɉɛɴɟɤɬ A
    Ɉɛɴɟɤɬ C
    --------
    Ɉɛɴɟɤɬ Делегат MyDelegate объявлен командой delegate void MyDelegate(). Экземпляры делегата могут ссылаться на методы, не имеющие аргументов и не возвращающие результат. В программе описывается класс
    MyClass с открытым текстовым полем name. У класса есть конструктор с текстовым аргументом, который присваивается в качестве значения полю name создаваемого объекта. Также в классе описан метод show(), при вызове отображающий в консольном окне значение текстового поля name
    . У метода нет аргументов, ион не возвращает результат.
    В классе MulticastDemo, кроме главного метода Main(), есть еще и статический метод makeLine(). У метода makeLine() нет аргументов, ион не возвращает результат. При вызове метода в консольном окне отображается импровизированная линия из дефисов НАЗ А МЕТКУ Таким образом, и статический метод makeLine()
    , и нестатический метод show()
    из класса
    MyClass соответствуют требованиям, которые «задекларированы» при объявлении делегата Поэтому экземпляр делегата может ссылаться на оба эти метода.
    В методе Main() последовательно создаются три объекта A, B и C класса. Поле name каждого из объектов получает уникальное текстовое значение. Командой MyDelegate meth объявляется переменная
    Делегаты и события делегата MyDelegate. Пока эта переменная не ссылается на экземпляр делегата — мы его еще не создали. Экземпляр делегата создается (и ссылка на него записывается в переменную meth) при выполнении команды meth=A.show, которой ссылка на метод show() объекта A присваивается переменной meth. Команда выполняется так создается экземпляр делегата, который ссылается на метод show() объекта A, и ссылка на этот экземпляр записывается в переменную meth.
    q
    1   2   3   4   5   6   7   8   9   ...   40


    написать администратору сайта