Шаг 177.
Язык программирования C#. Начала.
Делегаты и события. Использование анонимных методов (окончание)

    На этом шаге мы рассмотрим еще один пример программы, иллюстрирующей использование анонимных методов.

    Еще одна программа немного напоминает приложение из предыдущего шага. Правда на этот раз последствия использования анонимного метода в качестве результата не такие экзотические. Обратимся к программному коду, приведенному ниже.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace pr177_1
{
    // Объявление делегата: 
    delegate double Powers(double x);
    
    // Главный класс:
    class Program
    {
        // Статический метод результатом возвращает ссылку 
        // на экземпляр делегата: 
        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));
            }
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

    При выполнении программы получаем следующий результат:


Рис.1. Результат выполнения программы

    Здесь мы объявляем делегат Powers для работы с методами, у которых один аргумент типа double и такого же типа результат. В главном методе мы описываем статический метод maker(). Он имеет целочисленный аргумент (обозначен как n), а в качестве результата возвращает ссылку на экземпляр делегата Powers. В теле метода объявляется локальная переменная meth типа Powers. Значением этой переменной присваивается такой анонимный метод:

            meth = delegate(double x) { 
                double s = 1;
                // Вычисление произведения: 
                for(int i = 1;i <= n; i++) { 
                    s *= x;
                }
                return s; // Результат анонимного метода
            };

    У метода один аргумент (обозначен как x) типа double, а результатом метод возвращает значение аргумента x в степени, определяемой параметром n (аргумент метода maker()). Для вычисления результата использована конструкция цикла, в которой переменная s с начальным значением 1 умножается на x ровно n раз. Ссылка на экземпляр делегата, на который ссылается переменная meth, возвращается результатом метода maker(). Таким образом, при вызове метода maker() с некоторым целочисленным аргументом n мы получаем ссылку на метод (точнее, ссылку на экземпляр делегата, который ссылается на метод). Этот метод при вызове с аргументом x возвращает результатом x в степени n.

    В главном методе командами

  Powers sqr = maker(2);
и
  Powers cube = maker(3);
объявляются две переменные sqr и cube типа Powers, и им присваиваются значения. Значением выражения вида sqr(i) является значение аргумента i в степени 2, а значение выражения cube(i) - это значение аргумента i в степени 3. Далее, значение выражения maker(4) - это ссылка на метод, который результатом возвращает значение своего аргумента в четвертой степени. Поэтому значение выражения вида maker(4)(i) есть не что иное, как значение аргумента i в степени 4. Таблица, отображаемая в результате выполнения программы, подтверждает наши выводы.

    На следующем шаге мы рассмотрим лямбда-выражения.




Предыдущий шаг Содержание Следующий шаг