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

  • Использование делегатов

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


    Скачать 5.54 Mb.
    НазваниеВасильев А. Н. Программирование
    АнкорВасильев А.Н. Основы программирования на C
    Дата20.09.2022
    Размер5.54 Mb.
    Формат файлаpdf
    Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
    ТипДокументы
    #686596
    страница6 из 40
    1   2   3   4   5   6   7   8   9   ...   40
    ПОДРОБНОСТИ bУместно напомнить, что доступ к экземпляру делегата мы получаем через переменную делегата (аналог объектной переменной. Если такой переменной в качестве значения присвоить ссылку на метод, то автоматически будет создан экземпляр делегата, ссылающегося на метода в переменную будет записана ссылка на экземпляр делегата. Командой
    MyDelegate meth мы только объявили переменную. Экземпляр делегата создается, когда переменной meth присваивается значение (ссылка на метод. В принципе, можно создавать экземпляр делегата и с помощью выражения на основе new
    -инструкции.
    При выполнении команды meth() из объекта A вызывается метод show()
    . Затем выполняется команда meth=makeLine. Формально здесь переменной meth присваивается новое значение. Нов действительности происходит следующее. Создается новый экземпляр делегата, который ссылается на статический метод makeLine(). Ссылка на экземпляр делегата записывается в переменную meth, а ее связь с прежним экземпляром делегата (который ссылался на метод show() объекта A) теряется. Внешне все выглядит так, как если бы экземпляр делегата, отождествляемый с переменной meth, получал ссылку на метод makeLine(). А вот выполнение команды meth+=A.show приводит к тому, что в экземпляр делегата добавляется еще и ссылка на метод show() объекта A. При этом метод makeLine() также остается в списке вызовов экземпляра делегата. Командами meth+=B.show ив список вызовов последовательно добавляются методы show() объектов B и C. Поэтому при вызове экземпляра делегата командой meth() будут выполнены вызовы makeLine(), A.show(),
    B.show()
    и C.show() — строго в той последовательности, в которой методы добавлялись в список вызовов.
    После выполнения команды meth-=B.show из списка вызовов экземпляра делегата meth удаляется метод show() объекта B. При выполнении
    Глава вызова экземпляра делегата командой meth() теперь последовательно выполняются вызовы makeLine(), A.show() и C.show(). Если после этого выполнить команду meth=meth-A.show, то из списка вызовов будет удален еще и метод show() объекта A. Вызов экземпляра делегата командой meth() приведет к выполнению вызовов makeLine() и C.show().
    q
    ПОДРОБНО СТ ИВ список вызовов экземпляра делегата можно добавлять несколько раз один и тот же метод (подрядили нет. Если из списка вызовов удаляется метод, который представлен в этом списке несколько раз, то удаляется последняя добавленная ссылка на этот метод. Если попытаться удалить метод, которого в списке вызовов нетто не произойдет ничего.
    Методы в списке вызовов могут возвращать результат. Если так, то при вызове экземпляра делегата, ссылающегося на список вызовов, результатом возвращается значение, возвращаемое последним методом в списке вызовов.
    Использование делегатов
    Он бы прямо на митингах мог деньги зарабатывать. Первоклассный деляга.
    из к/ф Собачье сердце»
    В этом разделе мы рассмотрим несколько примеров, которые иллюстрируют красоту и мощь делегатов. Начнем с примера из листинга 2.3, в котором экземпляр делегата (точнее, переменная, которая может ссылаться на экземпляр делегата) является полем в классе Листинг 2.3. Экземпляр делегата как поле класса System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate void MyDelegate(string txt);
    //
    Ʉɥɚɫɫ ɫ ɩɨɥɟɦ, ɹɜɥɹɸɳɢɦɫɹ ɫɫɵɥɤɨɣ ɧɚ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    class MyClass{
    //
    ɉɨɥɟ ɹɜɥɹɟɬɫɹ ɫɫɵɥɤɨɣ ɧɚ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    Делегаты и события public MyDelegate apply;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ:
    public MyClass(MyDelegate md){
    apply=md;
    }
    }
    //
    Ʉɥɚɫɫ:
    class Alpha{
    //
    Ɂɚɤɪɵɬɨɟ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ:
    private string name;
    //
    Ɇɟɬɨɞ ɞɥɹ ɩɪɢɫɜɚɢɜɚɧɢɹ ɡɧɚɱɟɧɢɹ ɩɨɥɸ:
    public void set(string t){
    name=t;
    }
    //
    ɉɟɪɟɨɩɪɟɞɟɥɟɧɢɟ ɦɟɬɨɞɚ ToString():
    public override string ToString(){
    return name;
    }
    }
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class DelegateAsFieldDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
    Alpha A=new Alpha();
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ
    // (
    ɚɪɝɭɦɟɧɬ ɤɨɧɫɬɪɭɤɬɨɪɚ — ɫɫɵɥɤɚ ɧɚ ɦɟɬɨɞ):
    MyClass obj=new MyClass(A.set);
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    obj.apply(
    ƎɈɛɴɟɤɬ AƎ);
    //
    ɉɪɨɜɟɪɤɚ ɩɨɥɹ ɨɛɴɟɤɬɚ:
    Console.WriteLine(A);
    Глава 2
    74
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
    Alpha B=new Alpha();
    //
    ɉɨɥɸ ɡɧɚɱɟɧɢɟɦ ɩɪɢɫɜɚɢɜɚɟɬɫɹ ɫɫɵɥɤɚ ɧɚ ɦɟɬɨɞ:
    obj.apply=B.set;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    obj.apply(
    ƎɈɛɴɟɤɬ BƎ);
    //
    ɉɪɨɜɟɪɤɚ ɩɨɥɹ ɨɛɴɟɤɬɚ:
    Console.WriteLine(B);
    //
    Ⱦɨɛɚɜɥɟɧɢɟ ɦɟɬɨɞɚ ɜ ɫɩɢɫɨɤ ɜɵɡɨɜɨɜ ɷɤɡɟɦɩɥɹɪɚ
    //
    ɞɟɥɟɝɚɬɚ:
    obj.apply+=A.set;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    obj.apply(
    ƎɈɛɴɟɤɬ XƎ);
    //
    ɉɪɨɜɟɪɤɚ ɩɨɥɟɣ ɨɛɴɟɤɬɨɜ:
    Console.WriteLine(A+
    Ǝ ɢ Ǝ+B);
    //
    ɍɞɚɥɟɧɢɟ ɦɟɬɨɞɚ ɢɡ ɫɩɢɫɤɚ ɜɵɡɨɜɨɜ ɷɤɡɟɦɩɥɹɪɚ
    //
    ɞɟɥɟɝɚɬɚ:
    obj.apply-=B.set;
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    obj.apply(
    ƎɈɛɴɟɤɬ AƎ);
    //
    ɉɪɨɜɟɪɤɚ ɩɨɥɟɣ ɨɛɴɟɤɬɨɜ:
    Console.WriteLine(A+
    Ǝ ɢ Ǝ+B);
    Результат выполнения программы представлен ниже Результат выполнения программы (из листинга 2.3)

    Ɉɛɴɟɤɬ A
    Ɉɛɴɟɤɬ B
    Ɉɛɴɟɤɬ X ɢ Ɉɛɴɟɤɬ X
    Ɉɛɴɟɤɬ A ɢ Ɉɛɴɟɤɬ X
    Делегаты и события
    75
    Делегат MyDelegate объявляется командой delegate void
    MyDelegate(string txt). Экземпляры делегата смогут ссылаться на методы, имеющие один текстовый аргумент и не возвращающие результат. В классе MyClass описано поле apply, типом которого указан делегат. Это означает, что поле apply может ссылаться на метод (или список методов. Но самое важное — мы можем вызывать это поле (передав ему один текстовый аргумент. Также в классе описан конструктор с одним аргументом. Аргумент конструктора тоже примечательный это переменная md типа MyDelegate. В теле конструктора командой apply=md аргумент, переданный конструктору, присваивается значением полю apply.
    q
    ПОДРОБНОСТИ bЕсли в качестве типа переменной указан делегат, то такая переменная, по своей сути, является ссылкой на метод (который соответствует параметрам делегата. Во всяком случае, значением переменной может присваиваться ссылка на метод. Правда происходит все немного сложнее когда переменной типа делегата присваивается ссылка на метод, создается экземпляр делегата, переменная ссылается на этот экземпляр делегата, а экземпляр делегата ссылается на метод. Фактически экземпляр делегата является посредником между переменной и методом. Нов практическом плане, для понимания происходящего, обычно можно отождествлять переменную типа делегата (как поле apply или аргумент конструктора класса
    MyClass
    ) со ссылкой на метод.
    Еще один класс Alpha имеет закрытое текстовое поле name. Для присваивания значения полю предусмотрен открытый метод set(), имеющий текстовый аргумент и не возвращающий результат. Для считывания значения поля name мы переопределяем метод ToString() (метод результатом возвращает значение поля В методе Main() командой Alpha A=new Alpha() создается объект класса Alpha. После этого командой MyClass obj=new MyClass
    (A.set)
    мы создаем объект класса MyClass. Пикантность ситуации в том, что аргументом конструктору класса MyClass передается ссылка
    A.set на метод set() объекта A.
    q
    ПОДРОБНО СТ ИВ несколько упрощенном виде общая последовательность действий такая. Аргумент конструктора класса
    MyClass объявлен как
    Глава переменная типа
    MyDelegate
    . При вызове конструктора для записи аргумента выделяется место в памяти — то есть создается техническая переменная типа
    MyDelegate
    . Аргументом конструктору передается ссылка
    A.set
    , которая и присваивается технической переменной. В результате создается экземпляр делегата, который ссылается на метод set()
    объекта
    A
    , а техническая переменная (аргумент конструктора) ссылается на этот экземпляр. В теле конструктора, при выполнении команды apply=md
    , значение технической переменной копируется в поле apply
    . В результате поле apply ссылается на экземпляр делегата, который ссылается на метод set()
    объекта Поэтому при выполнении команды obj.apply(
    ƎɈɛɴɟɤɬ AƎ), вызывающей экземпляр делегата, на который ссылается поле apply, с аргументом
    ƎɈɛɴɟɤɬ AƎ вызывается метод set() объекта A. Полю name объекта A присваивается значение, что подтверждается при выполнении команды. Затем командой Alpha B=new Alpha() создается еще один объект класса Alpha. С помощью команды obj.
    apply=B.set поле apply связывается с методом set() объекта B. Поэтому после выполнения команды obj.apply(
    ƎɈɛɴɟɤɬ BƎ) присваивается значение полю name объекта B. Это значение проверяем командой Командой obj.apply+=A.set в список вызовов экземпляра делегата apply добавляется метод set() объекта A. И когда выполняется команда, то из объектов B и A последовательно вызывается метод set() с аргументом
    ƎɈɛɴɟɤɬ XƎ. В результате поле name каждого из объектов получает значение
    ƎɈɛɴɟɤɬ XƎ, в чем мы и убеждаемся с помощью команды Console.WriteLine(A+
    Ǝ ɢ Наконец, выполнение команды obj.apply-=B.set приводит к удалению метода set() объекта B из списка вызовов экземпляра делегата apply
    . Поэтому при выполнении команды obj.apply(
    ƎɈɛɴɟɤɬ AƎ) меняется значение поля name только для объекта В следующем примере мы используем делегат для того, чтобы передавать ссылки на методы аргументом другому методу. Программа достаточно простая описывается статический метод, который используется для того, чтобы создать таблицу значений другого метода. Таблица формируется так. Берется некоторый методу которого целочисленный аргумент и который возвращает целочисленный результат. Аргумент метода изменяется в заданных пределах. Для каждого значения аргумента отображается значение метода. Этот простой алгоритм не зависит
    Делегаты и события
    77
    от того, для какого именно метода строится таблица значений. Главное, чтобы у метода был целочисленный аргумент, ион должен возвращать целочисленный результат. Именно та ситуация, когда разумно использовать делегаты. Рассмотрим программный код, представленный в листинге Листинг 2.4. Передача метода в качестве аргумента System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate int MyDelegate(int n);
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class DelegateAsArgDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɧɟɱɟɬɧɵɯ ɱɢɫɟɥ:
    static int f(int n){
    return 2*n+1;
    }
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɱɟɬɧɵɯ ɱɢɫɟɥ:
    static int g(int n){
    return 2*n;
    }
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɞɥɹ ɜɵɱɢɫɥɟɧɢɹ ɤɜɚɞɪɚɬɨɜ ɱɢɫɟɥ:
    static int h(int n){
    return n*n;
    }
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ, ɤɨɬɨɪɨɦɭ ɚɪɝɭɦɟɧɬɨɦ
    //
    ɩɟɪɟɞɚɟɬɫɹ ɫɫɵɥɤɚ ɧɚ ɦɟɬɨɞ:
    static void display(MyDelegate F,int a,int b){
    Console.WriteLine(
    Ǝ{0,-4}|{1,4}Ǝ,ƎxƎ,Ǝ F(x)Ǝ);
    Console.WriteLine(
    Ǝ----------Ǝ);
    for(int k=a;k<=b;k++){
    //
    Ʉɨɦɚɧɞɚ ɫ ɜɵɡɨɜɨɦ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.WriteLine(
    Ǝ{0,-4}|{1,4}Ǝ,k,F(k));
    }
    Глава 2
    78
    Console.WriteLine();
    }
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    Ⱦɢɚɩɚɡɨɧ ɢɡɦɟɧɟɧɢɹ ɚɪɝɭɦɟɧɬɚ:
    int a=0,b=5;
    Console.WriteLine(
    Ǝɇɟɱɟɬɧɵɟ ɱɢɫɥɚ:Ǝ);
    //
    ɉɟɪɟɞɚɱɚ ɚɪɝɭɦɟɧɬɨɦ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ:
    display(f,a,b);
    Console.WriteLine(
    Ǝɑɟɬɧɵɟ ɱɢɫɥɚ:Ǝ);
    //
    ɉɟɪɟɞɚɱɚ ɚɪɝɭɦɟɧɬɨɦ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ:
    display(g,a,b);
    Console.WriteLine(
    Ǝɑɢɫɥɨ ɜ ɤɜɚɞɪɚɬɟ:Ǝ);
    //
    ɉɟɪɟɞɚɱɚ ɚɪɝɭɦɟɧɬɨɦ ɫɫɵɥɤɢ ɧɚ ɦɟɬɨɞ:
    display(h,a,b);
    В результате выполнения программы получаем следующее Результат выполнения программы (из листинга 2.4)

    ɇɟɱɟɬɧɵɟ ɱɢɫɥɚ:
    x | F(x)
    ----------
    0 | 1 1 | 3 2 | 5 3 | 7 4 | 9 5 | 11
    Делегаты и события ɱɢɫɥɚ:
    x | F(x)
    ----------
    0 | 0 1 | 2 2 | 4 3 | 6 4 | 8 5 | 10
    ɑɢɫɥɨ ɜ ɤɜɚɞɪɚɬɟ:
    x | F(x)
    ----------
    0 | 0 1 | 1 2 | 4 3 | 9 4 | 16 5 | Программа небольшая и простая. В программе командой delegate int
    MyDelegate(int n) объявляется делегат, экземпляр которого может ссылаться на метод, имеющий целочисленный аргумент и возвращающий целочисленный результат. В классе с главным методом программы описано еще несколько статических методов. Методы f(), g()
    и h() соответствуют параметрам делегата MyDelegate: у каждого из этих методов один целочисленный аргумент, и каждый метод результатом возвращает целое число. При заданном целочисленном аргументе метод f() возвращает значение 2*n+1 (нечетное число, метод g() возвращает значение 2*n (четное число, а метод h() возвращает значение n*n (число в квадрате. Еще один статический метод display()
    описан стремя аргументами. Первый аргумент F имеет тип
    MyDelegate
    — то есть это переменная, которая может ссылаться на экземпляр делегата. Мы уже знаем, что такой переменной можно присваивать ссылку на метод. Поэтому при вызове метода первым аргументом
    Глава можно передавать ссылку на метод (с целочисленным аргументом и целочисленным результатом. Другими словами, под аргументом F мы можем подразумевать название метода, который можно вызывать, передав ему целочисленный аргумент. Еще два целочисленных аргумента (a и b) определяют диапазон, на котором табулируется переданный первым аргументом метод. Табуляция выполняется просто с помощью оператора цикла в консоль выводится значение аргумента k и значение метода F(k).
    q
    ПОДРОБНО СТ ИВ командах
    Console.WriteLine("{0,-4}|{1,4}","x"," и
    Console.WriteLine("{0,-4}|{1,4}",k,F(k))
    инструкция означает, что под отображаемое значение выделяется
    4
    позиции и выравнивание выполняется полевому краю. Инструкция означает, что под отображаемое значение выделяется
    4
    позиции и выравнивание выполняется по правому краю.
    В главном методе программы при заданных значениях переменных a и b командами display(f,a,b), display(g,a,b) и display(h,a,b) табулируются методы f(), g() и h() соответственно. Чтобы передать метод аргументом методу display(), достаточно указать имя метода первым аргументом метода display(). Например, при выполнении команды display(f,a,b) выполняется код метода display(), но только вместо аргумента F в программном коде следует подразумевать. Тоже касается и других команд с вызовом Еще один пример, который мы рассмотрим, касается ситуации, когда с помощью делегатов мы создаем иллюзию (хотя это и не совсем иллюзия, что результатом выражения является метод. Рассмотрим программный код, представленный в листинге 2.5.
    
    Листинг 2.5. Экземпляр делегата как значение выражения System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate int Method(int n);
    //
    Ʉɥɚɫɫ ɫ ɢɧɞɟɤɫɚɬɨɪɨɦ:
    class MyClass{
    //
    Ɂɚɤɪɵɬɨɟ ɰɟɥɨɱɢɫɥɟɧɧɨɟ ɩɨɥɟ:
    private int num;
    Делегаты и события //
    Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɰɟɥɨɱɢɫɥɟɧɧɵɦ ɚɪɝɭɦɟɧɬɨɦ:
    public MyClass(int n){
    num=n;
    }
    //
    ɉɟɪɜɵɣ ɡɚɤɪɵɬɵɣ ɦɟɬɨɞ:
    private int first(int n){
    return n+num;
    }
    //
    ȼɬɨɪɨɣ ɡɚɤɪɵɬɵɣ ɦɟɬɨɞ:
    private int second(int n){
    return n-num;
    }
    //
    Ɍɪɟɬɢɣ ɡɚɤɪɵɬɵɣ ɦɟɬɨɞ:
    private int third(int n){
    return n*num;
    }
    //
    ɂɧɞɟɤɫɚɬɨɪ ɫ ɰɟɥɨɱɢɫɥɟɧɧɵɦ ɢɧɞɟɤɫɨɦ.
    //
    Ɋɟɡɭɥɶɬɚɬ - ɫɫɵɥɤɚ ɧɚ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    public Method this[int k]{
    //
    Ⱥɤɫɟɫɫɨɪ ɞɥɹ ɫɱɢɬɵɜɚɧɢɹ ɡɧɚɱɟɧɢɹ:
    get{
    switch(k){
    case 0:
    return first;
    case 1:
    return second;
    default:
    return third;
    }
    }
    }
    }
    Глава 2
    82
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class DelegateAsResDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɉɟɪɟɦɟɧɧɚɹ:
    int x=12;
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
    MyClass obj=new MyClass(4);
    //
    ɂɧɞɟɤɫɢɪɨɜɚɧɢɟ ɨɛɴɟɤɬɚ:
    for(int k=0;k<=2;k++){
    Console.WriteLine(
    Ǝobj[{0}]({1})={2}Ǝ,k,x,obj[k](x));
    }
    При выполнении программы получим следующий результат Результат выполнения программы (из листинга Делегат Method объявляется командой delegate int Method(int n) и соответствует методам с одним целочисленным аргументом и целочисленным результатом. В классе MyClass мы описываем закрытое целочисленное поле num, значение которому присваивается при создании объекта. Еще в классе описаны три закрытых метода. Метод first() возвращает в качестве результата сумму значения своего аргумента и поля num. Метод second() результатом возвращает разность аргумента и поля num. Метод third() возвращает результатом произведение значений аргумента и поля num. Еще раз подчеркнем, что все три метода закрытые, поэтому прямого доступа к ним вне пределов класса нет. Нов классе описан индексатор с get-аксессором. Тип результата, возвращаемого аксессором, указан как Method. Это означает, что при индексировании объекта мы результатом получаем ссылку на экземпляр
    Делегаты и события
    83
    делегата Method. Но фактически это ссылка на метод, который соответствует параметрам делегата Method.
    Индексатор описан так, что если индекс равен 0, то результатом возвращается значение first (ссылка на метод first() индексируемого объекта. Если индекс равен 1, то результатом возвращается значение (ссылка на метод second() индексируемого объекта. При всех других значениях индекса результатом возвращается ссылка third на метод third() индексируемого объекта ПОДРОБНО СТ ИВ описании аксессора указано, что результатом он возвращает значение типа
    Method
    . Что это означает Это значит, что результатом аксессора является ссылка на экземпляр делегата
    Method
    . При вызове аксессора для записи результата выделяется переменная (типа
    Method
    ). Эта переменная может ссылаться на экземпляр делегата. Фактическим значением аксессор возвращает ссылку на метод. Получается, что переменной типа
    Method присваивается ссылка на метод. В этом случае, как мы помним, автоматически создается экземпляр делегата, который ссылается на метод. Ссылка на экземпляр делегата записывается в переменную, выделенную для запоминания результата аксессора.
    В главном методе программы мы проверяем работу индексатора. Для этого командой MyClass obj=new MyClass(4) создаем объект obj класса MyClass. Целочисленное поле num этого объекта равно 4 (аргумент конструктора. Далее для переменной x со значением 12 в операторе цикла при фиксированном значении переменной k (изменяется в пределах от 0 до 2 включительно) вычисляется значение выражения. Несложно заметить, что в этом случае с аргументом из объекта obj последовательно вызываются методы first(), second()
    и third().
    {
    1   2   3   4   5   6   7   8   9   ...   40


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