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

  • Лямбда-выражения

  • A.method=n=>A.number+n; // ɉɨɥɸ ɨɛɴɟɤɬɚ ɡɧɚɱɟɧɢɟɦ ɩɪɢɫɜɚɢɜɚɟɬɫɹ // ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ: B.method=(int n)=>{ return B.number-n; };

  • show=t=>Console.WriteLine(“ Ɍɟɤɫɬ: \”{0}\””,t); show(ƎBravoƎ); // ɉɪɢɫɜɚɢɜɚɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɹ: show=(string t)=>{

  • MyClass obj=new MyClass( ƍKƍ,n=>(char)(ƍAƍ+n));

  • return ()=>{ count+=n; return count; };

  • Листинг 2.14. Реализация результата с помощью лямбда-выражения

  • meth=x=>{ double s=1; for(int i=1;i s*=x; } return s; };

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


    Скачать 5.54 Mb.
    НазваниеВасильев А. Н. Программирование
    АнкорВасильев А.Н. Основы программирования на C
    Дата20.09.2022
    Размер5.54 Mb.
    Формат файлаpdf
    Имя файлаVasilev_Programmirovanie-na-C-dlya-nachinayushchih-Osobennosti-y.pdf
    ТипДокументы
    #686596
    страница8 из 40
    1   ...   4   5   6   7   8   9   10   11   ...   40
    ПОДРОБНОСТИ bПри вызове метода set()
    мы использовали анонимный метод, содержащий ссылку obj.symbol
    . Здесь нет ошибки, поскольку на момент вызова метода set()
    в переменную obj уже была записана ссылка на объект. В конструкторе, при создании объекта obj
    , мы не могли использовать ссылку obj.symbol
    . Причина очевидна сначала вычисляются аргументы конструктора, а уже затем выполняется его код. Ссылка на объект записывается в переменную obj после того, как объект создан. Поэтому при вычислении аргументов конструктора переменная obj еще не содержит ссылку на объект
    Делегаты и события
    97
    Анонимный метод может возвращаться в качестве результата другого метода. В листинге 2.9 поэтому поводу представлен пример Листинг 2.9. Анонимный метод как результат System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate int MyDelegate();
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class AnonymAsResultDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢ ɦɟɬɨɞ ɪɟɡɭɥɶɬɚɬɨɦ ɜɨɡɜɪɚɳɚɟɬ ɫɫɵɥɤɭ ɧɚ
    //
    ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    static MyDelegate calculate(int n){
    //
    Ʌɨɤɚɥɶɧɚɹ ɩɟɪɟɦɟɧɧɚɹ:
    int count=0;
    //
    Ɋɟɡɭɥɶɬɚɬ ɪɟɚɥɢɡɨɜɚɧ ɱɟɪɟɡ ɚɧɨɧɢɦɧɵɣ ɦɟɬɨɞ:
    return delegate(){
    count+=n;
    return count;
    };
    }
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɉɟɪɟɦɟɧɧɚɹ ɬɢɩɚ ɞɟɥɟɝɚɬɚ:
    MyDelegate next=calculate(1);
    for(int i=1;i<=5;i++){
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.Write(next()+
    Ǝ Ǝ);
    }
    Console.WriteLine();
    //
    ɇɨɜɨɟ ɡɧɚɱɟɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɬɢɩɚ ɞɟɥɟɝɚɬɚ:
    next=calculate(3);
    for(int i=1;i<=5;i++){
    Глава 2
    98
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɚ ɞɟɥɟɝɚɬɚ:
    Console.Write(next()+
    Ǝ Ǝ);
    }
    Console.WriteLine();
    При выполнении программы получаем такой результат Результат выполнения программы (из листинга 2.9)

    1 2 3 4 5 3 6 9 12 Делегат MyDelegate описан для создания экземпляров, которые могут ссылаться на методы без аргументов, возвращающие целочисленный результат. Еще мы описываем статический методу которого целочисленный аргумент (обозначен как n) и который результатом возвращает ссылку на экземпляр делегата MyDelegate. В теле метода объявлена локальная целочисленная переменная count с начальным нулевым значением. Далее следует инструкция и возвращаемым значением указано следующее выражение (после этого выражения в коде метода стоит точка с запятой count+=n;
    return Это код анонимного метода без аргументов, который результатом возвращает целое число. Этот анонимный метод возвращается результатом метода calculate().
    q
    ПОДРОБНОСТИ bТип результата для метода calculate()
    указан как Формально это ссылка на экземпляр делегата
    MyDelegate
    . При вызове метода calculate()
    под результат метода выделяется переменная типа делегата
    MyDelegate
    . Результатом метод calculate()
    Делегаты и события
    99
    возвращает анонимный метод, который присваивается переменной, выделенной для записи результата. В итоге создается экземпляр делегата, который ссылается на анонимный метод. Ссылка на этот экземпляр записывается в переменную, выделенную для запоминания результата метода calculate()
    . Поэтому результатом метода calculate()
    является ссылка на экземпляр делегата
    MyDelegate
    , а этот экземпляр ссылается на упомянутый выше анонимный метод.
    В главном методе программы командой MyDelegate next=calculate(1)
    объявляется переменная next типа делегата
    MyDelegate
    , и значением ей присваивается результат вызова метода calculate()
    с аргументом 1. Затем с помощью оператора цикла несколько раз подряд вычисляется значение выражения next(). И каждый раз мы получаем новое значение (числа 1, 2, 3 итак далее. Почему так происходит При вызове метода calculate() с аргументом 1 создается локальная переменная count с начальным значением 0. Мы уже знаем, что метод calculate() возвращает результатом анонимный метод, который при вызове каждый раз увеличивает значение переменной (в данном случае на 1) и это новое значение возвращает как результат. В итоге получается так переменная next ссылается на экземпляр делегата, который ссылается на анонимный метода этот метод содержит ссылку на переменную count, созданную при вызове метода calculate()
    . После завершения вызова метода calculate() локальная переменная count должна бы удаляться. Но поскольку на эту переменную есть ссылка в анонимном методе, то она выживает. После первого вызова анонимного метода через переменную next значение переменной становится равным 1. При втором вызове она становится равной 2 итак далее. Поэтому при вычислении значения выражения) мы каждый раз получаем новое число (на единицу больше предыдущего).
    После выполнения команды next=calculate(3) в переменную next записывается ссылка на новый экземпляр делегата, ссылающийся на новый анонимный метод, который ссылается на новую локальную переменную. Она получила начальное значение 0 при вызове метода calculate()
    . И теперь каждый раз при вычислении значения выражения) мы получаем новое число, большее предыдущего на Еще одна программа немного напоминает предыдущую. Правда на этот раз последствия использования анонимного метода в качестве результата не такие экзотические. Обратимся к программному коду из листинга 2.10.
    Глава 2
    100
    
    Листинг 2.10. Реализация результата с помощью анонимного метода System;
    //
    Ɉɛɴɹɜɥɟɧɢɟ ɞɟɥɟɝɚɬɚ:
    delegate double Powers(double x);
    //
    Ƚɥɚɜɧɵɣ ɤɥɚɫɫ:
    class MoreAnonymAsResultDemo{
    //
    ɋɬɚɬɢɱɟɫɤɢɣ ɦɟɬɨɞ ɪɟɡɭɥɶɬɚɬɨɦ ɜɨɡɜɪɚɳɚɟɬ ɫɫɵɥɤɭ
    //
    ɧɚ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    static Powers maker(int n){
    //
    Ʌɨɤɚɥɶɧɚɹ ɩɟɪɟɦɟɧɧɚɹ ɬɢɩɚ ɞɟɥɟɝɚɬɚ:
    Powers meth;
    //
    Ɂɧɚɱɟɧɢɟɦ ɩɟɪɟɦɟɧɧɨɣ ɬɢɩɚ ɞɟɥɟɝɚɬɚ ɩɪɢɫɜɚɢɜɚɟɬɫɹ
    //
    ɚɧɨɧɢɦɧɵɣ ɦɟɬɨɞ:
    meth=delegate(double x){
    double s=1;
    //
    ȼɵɱɢɫɥɟɧɢɟ ɩɪɨɢɡɜɟɞɟɧɢɹ:
    for(int i=1;i<=n;i++){
    s*=x;
    }
    return s; //
    Ɋɟɡɭɥɶɬɚɬ ɚɧɨɧɢɦɧɨɝɨ ɦɟɬɨɞɚ
    };
    return meth; //
    Ɋɟɡɭɥɶɬɚɬ ɫɬɚɬɢɱɟɫɤɨɝɨ ɦɟɬɨɞɚ
    }
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɉɟɪɜɵɣ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    Powers sqr=maker(2);
    //
    ȼɬɨɪɨɣ ɷɤɡɟɦɩɥɹɪ ɞɟɥɟɝɚɬɚ:
    Powers cube=maker(3);
    //
    ȼɵɡɨɜ ɷɤɡɟɦɩɥɹɪɨɜ ɞɟɥɟɝɚɬɚ:
    for(int i=1;i<=5;i++){
    Делегаты и события Console.WriteLine(
    Ǝ{0,2}:{1,5}{2,5}{3,5}Ǝ, i,sqr(i),cube(i),maker(4)(i));
    }
    При выполнении программы получаем следующий результат Результат выполнения программы (из листинга 2.10)

    1: 1 1 1 2: 4 8 16 3: 9 27 81 4: 16 64 256 5: 25 125 Здесь мы объявляем делегат Powers для работы с методами, у которых один аргумент типа double и такого же типа результат. В главном методе мы описываем статический метод maker(). Он имеет целочисленный аргумент (обозначен как n), а в качестве результата возвращает ссылку на экземпляр делегата Powers. В теле метода объявляется локальная переменная meth типа Powers. Значением этой переменной присваивается такой анонимный метод x){
    double s=1;
    for(int i=1;i<=n;i++){
    s*=x;
    }
    return У метода один аргумент (обозначен как x) типа double, а результатом метод возвращает значение аргумента x в степени, определяемой параметром n (аргумент метода maker()). Для вычисления результата использован оператор цикла, в котором переменная s с начальным значением 1 умножается на x ровно n раз. Ссылка на экземпляр делегата, на который ссылается переменная meth, возвращается результатом
    Глава метода maker(). Таким образом, при вызове метода maker() с некоторым целочисленным аргументом n мы получаем ссылку на метод (точнее, ссылку на экземпляр делегата, который ссылается на метод. Этот метод при вызове с аргументом x возвращает результатом x в степени В главном методе командами Powers sqr=maker(2) и Powers cube=maker(3)
    объявляются две переменные sqr и cube типа
    Powers
    , и им присваиваются значения. Значением выражения вида sqr(i)
    является значение аргумента i в степени 2, а значение выражения это значение аргумента i в степени 3. Далее, значение выражения maker(4) — это ссылка на метод, который результатом возвращает значение своего аргумента в четвертой степени. Поэтому значение выражения вида maker(4)(i) есть нечто иное, как значение аргумента в степени 4. Таблица, отображаемая в результате выполнения программы, подтверждает наши выводы.
    Лямбда-выражения
    А, ничего опасного. Никакой контрреволюции.
    из к/ф Собачье сердце»
    У анонимных методов есть конкурент — это
    лямбда-выражения. Лямб- да-выражение представляет собой блок программного кода, который определяет метод и предназначен для присваивания в качестве значения переменной типа делегата. В этом смысле и лямбда-выражения, и анонимные методы служат одной цели. Разница лишь в том, как эта цель достигается.
    Итак, лямбда-выражение определяет метод. Как же это происходит Синтаксис описания лямбда-выражения идеологически близок копи- санию анонимного метода, нов несколько упрощенном виде. Условно лямбда-выражение можно рассматривать как состоящее из двух частей (левой и правой. Между ними размещается оператор =>. Левая часть определяет аргументы метода. В общем случае аргументы описываются в круглых скобках, для каждого аргумента указывается его тип и название. То есть фактически это круглые скобки с описанием аргументов метода. Отсутствие аргументов отображается пустыми круглыми скобками. В правой части, после оператора => описывается выделенный фигурными скобками блок, в котором размещаются команды,
    Делегаты и события
    103
    формирующие тело метода. Общий шаблон описания лямбда-метода такой (жирным шрифтом выделены основные элементы шаблона //
    Ɍɟɥɨ Строго говоря, если взять описание анонимного метода, убрать ключевое слово delegate и между блоками из круглых и квадратных скобок поставить оператор =>, то получим лямбда-выражение. Оно используется точно также, как и анонимный метод. Вместе стем при использовании лямбда-выражений можно использовать некоторые упрощения, которые часто делают описание соответствующего метода компактным. Ниже перечислены основные правила, которые позволяют упростить жизнь при работе с лямбда-выражениями:
    • Тип аргументов можно не указывать, если по контексту команды с лямб- да-выражением они могут быть определены автоматически (на основе переменной типа делегата, которой присваивается лямбда-выражение).
    • Если аргумент один и его тип не указывается, то круглые скобки можно не использовать Если в теле метода всего одна команда, то фигурные скобки можно не использовать Если в теле метода всего одна команда с инструкцией, то инструкцию можно не использовать.
    Например, ниже приведено лямбда-выражение, определяющее метод, который посимвольному и целочисленному аргументу вычисляет новый символ s,int n)=>{
    int k=s+n;
    return (Мы могли бы определить такой же метод несколько иначе return (char)(s+n);
    }
    Глава Или еще проще:
    (s,n)=>(char)(s+n)
    А вот пример лямбда-выражения для метода, который для заданного значения аргумента возвращает квадрат аргумента (произведение аргумента на самого себя):
    n=>n*n
    То же самое, с помощью анонимного метода, мы могли бы описать следующим образом n){
    return То есть экономия на программном коде очевидная. Далее мы рассмотрим несколько примеров, которые иллюстрируют, как вместо анонимных методов можно было бы использовать лямбда-выражения. В листинге 2.11 представлена версия программы из листинга 2.7, но вместо анонимных методов использованы лямбда-выражения (здесь и далее для сокращения объема кода несущественные комментарии удалены, а важные места выделены жирным шрифтом Листинг 2.11. Знакомство с лямбда-выражениями

    using System;
    delegate int Alpha(int n);
    delegate void Bravo(string t);
    class MyClass{
    public int number;
    public MyClass(int n){
    number=n;
    }
    public Alpha method;
    }
    Делегаты и события LambdaDemo{
    static void Main(){
    MyClass A=new MyClass(100);
    MyClass B=new MyClass(200);
    //
    ɉɨɥɸ ɨɛɴɟɤɬɚ ɡɧɚɱɟɧɢɟɦ ɩɪɢɫɜɚɢɜɚɟɬɫɹ
    //
    ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    A.method=n=>A.number+n;
    //
    ɉɨɥɸ ɨɛɴɟɤɬɚ ɡɧɚɱɟɧɢɟɦ ɩɪɢɫɜɚɢɜɚɟɬɫɹ
    //
    ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    B.method=(int n)=>{
    return B.number-n;
    };
    int x=80;
    Console.WriteLine(
    ƎA.method({0})={1}Ǝ,x,A.method(x));
    A.number=300;
    Console.WriteLine(
    ƎA.method({0})={1}Ǝ,x,A.method(x));
    Console.WriteLine(
    ƎB.method({0})={1}Ǝ,x,B.method(x));
    Bravo show;
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɹ:
    show=t=>Console.WriteLine(“
    Ɍɟɤɫɬ: \”{0}\””,t);
    show(
    ƎBravoƎ);
    //
    ɉɪɢɫɜɚɢɜɚɧɢɟ ɩɟɪɟɦɟɧɧɨɣ ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɹ:
    show=(string t)=>{
    for(int k=0;k
    Console.Write(“|”+t[k]);
    }
    Console.WriteLine(“|”);
    };
    show(
    ƎBravoƎ);
    }
    }
    Глава Результат выполнения программы следующий Результат выполнения программы (из листинга 2.11)
    A.method(80)=180
    A.method(80)=380
    B.method(80)=120
    Ɍɟɤɫɬ: В листинге 2.12 представлена новая версия программы из листинга 2.8.
    
    Листинг 2.12. Лямбда-выражение как аргумент System;
    delegate char MyDelegate(int n);
    class MyClass{
    public char symbol;
    public MyDelegate get;
    public MyClass(char s,MyDelegate md){
    symbol=s;
    get=md;
    }
    public void set(MyDelegate md){
    get=md;
    }
    }
    class LambdaAsArgDemo{
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ. ȼɬɨɪɵɦ ɚɪɝɭɦɟɧɬɨɦ ɹɜɥɹɟɬɫɹ
    //
    ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    MyClass obj=new MyClass(
    ƍKƍ,n=>(char)(ƍAƍ+n));
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ: \ƍ{0}\ƍƎ,obj.get(3));
    //
    ȼɵɡɨɜ ɦɟɬɨɞɚ, ɚɪɝɭɦɟɧɬɨɦ ɤɨɬɨɪɨɦɭ ɩɟɪɟɞɚɧɨ
    //
    ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    Делегаты и события obj.set(n=>(char)(obj.symbol+n));
    Console.WriteLine(
    Ǝɋɢɦɜɨɥ: \ƍ{0}\ƍƎ,obj.get(3));
    Ниже представлен результат выполнения программы Результат выполнения программы (из листинга 2.12)

    ɋɢɦɜɨɥ: 'D'
    ɋɢɦɜɨɥ: 'Программа в листинге 2.13 — это новая версия программы из листинга 2.9.
    
    Листинг 2.13. Лямбда-выражение как результат System;
    delegate int MyDelegate();
    class LambdaAsResultDemo{
    static MyDelegate calculate(int n){
    int count=0;
    //
    Ɋɟɡɭɥɶɬɚɬ ɪɟɚɥɢɡɨɜɚɧ ɱɟɪɟɡ ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    return ()=>{
    count+=n;
    return count;
    };
    }
    static void Main(){
    MyDelegate next=calculate(1);
    for(int i=1;i<=5;i++){
    Console.Write(next()+
    Ǝ Ǝ);
    }
    Console.WriteLine();
    next=calculate(3);
    for(int i=1;i<=5;i++){
    Глава 2
    108
    Console.Write(next()+
    Ǝ Ǝ);
    }
    Console.WriteLine();
    Результат выполнения программы такой Результат выполнения программы (из листинга 2.13)

    1 2 3 4 5 3 6 9 12 Наконец, в листинге 2.14 показано, как будет выглядеть программа из листинга 2.10, если вместо анонимных методов использовать лямб- да-выражения.
    
    Листинг 2.14. Реализация результата с помощью лямбда-выражения
    using System;
    delegate double Powers(double x);
    class MoreLambdaAsResultDemo{
    static Powers maker(int n){
    Powers meth;
    //
    Ɂɧɚɱɟɧɢɟɦ ɩɟɪɟɦɟɧɧɨɣ ɬɢɩɚ ɞɟɥɟɝɚɬɚ ɩɪɢɫɜɚɢɜɚɟɬɫɹ
    //
    ɥɹɦɛɞɚ-ɜɵɪɚɠɟɧɢɟ:
    meth=x=>{
    double s=1;
    for(int i=1;i<=n;i++){
    s*=x;
    }
    return s;
    };
    return meth;
    }
    static void Main(){
    Делегаты и события Powers sqr=maker(2);
    Powers cube=maker(3);
    for(int i=1;i<=5;i++){
    Console.WriteLine(
    Ǝ{0,2}:{1,5}{2,5}{3,5}Ǝ,i,sqr(i),cube(i),maker(4)(i));
    }
    Ниже приведен результат выполнения программы Результат выполнения программы (из листинга 2.14)
    1: 1 1 1 2: 4 8 16 3: 9 27 81 4: 16 64 256 5: 25 125 Во всех случаях, хотя программный код изменился, результат выполнения программ такой же, как и у их предшественниц.
    Несложно заметить, что для небольших (по объему кода) методов использование лямбда-выражений значительно упрощает структуру и читабельность программы.
    {
    i
    НАЗ А МЕТКУ Не все лямбда-выражения в примерах выше описаны оптимальным образом. Причина связана с желанием показать различные способы описания лямбда-выражений.
    Но различие между лямбда-выражениями и анонимными методами не сводится к чисто косметическим эффектам. Например, лямбда-выра- жения могут использоваться для описания индексаторов и свойств, которые имеют только get-аксессор. В таком случае вместо блока из фигурных скобок с аксессорами для свойства или индексатора указывается оператор => и значение, считываемое для свойства или индексатора. Небольшой пример поэтому поводу представлен в листинге 2.15.
    Глава 2
    110
    
    Листинг 2.15. Лямбда-выражения в свойствах и индексаторах
    using System;
    //
    Ʉɥɚɫɫ ɫɨ ɫɜɨɣɫɬɜɨɦ ɢ ɢɧɞɟɤɫɚɬɨɪɨɦ:
    class MyClass{
    //
    Ɂɚɤɪɵɬɨɟ ɬɟɤɫɬɨɜɨɟ ɩɨɥɟ:
    private string text;
    //
    Ʉɨɧɫɬɪɭɤɬɨɪ ɫ ɬɟɤɫɬɨɜɵɦ ɚɪɝɭɦɟɧɬɨɦ:
    public MyClass(string t){
    text=t;
    }
    //
    ɂɧɞɟɤɫɚɬɨɪ:
    public char this[int k]=>text[k];
    //
    ɋɜɨɣɫɬɜɨ:
    public int length=>text.Length;
    }
    //
    Ʉɥɚɫɫ ɫ ɝɥɚɜɧɵɦ ɦɟɬɨɞɨɦ:
    class MoreLambdaDemo{
    //
    Ƚɥɚɜɧɵɣ ɦɟɬɨɞ:
    static void Main(){
    //
    ɋɨɡɞɚɧɢɟ ɨɛɴɟɤɬɚ:
    MyClass obj=new MyClass(
    ƎAlphaƎ);
    //
    ɂɫɩɨɥɶɡɨɜɚɧɢɟ ɢɧɞɟɤɫɚɬɨɪɚ ɢ ɫɜɨɣɫɬɜɚ:
    for(int k=0;k Console.Write(
    Ǝ|Ǝ+obj[k]);
    }
    Console.WriteLine(
    Ǝ|Ǝ);
    }
    }
    Делегаты и события
    111
    Результат выполнения программы следующий Результат выполнения программы (из листинга Программа простая описывается класс MyClass с закрытым текстовым полем text. Значение полю присваивается при создании объекта (значение передается аргументом конструктору. Индексатор описан так char this[int Эта запись означает, что при считывании значения проиндексированного объекта результатом возвращается символ из текстового поля с индексом, указанным в квадратных скобках. Похожим образом описано целочисленное свойство length:
    public int Значением свойства возвращается размер текста в текстовом поле. В главном методе проверяется функциональность созданного кода класса.
    В завершение раздела заметим, что лямбда-выражения считаются более предпочтительным механизмом по сравнению с анонимными методами.
    1   ...   4   5   6   7   8   9   10   11   ...   40


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