Локальные функции в C# - C# и .NET

Локальные функции в C#

Локальные функции в C# – это методы, которые объявляются внутри тела другого метода. В этой части мы познакомимся с этим видом методов в C# и рассмотрим пример использования локальных функций в приложениях.

Локальные функции в C#

Синтаксис объявления локальной функции в C# следующий:

public void CoveringMethod()
{
    //переменные, инструкции метода
    
    // Объявление локальной функции
    void LocalFunction(int parameter)
    {
        // Тело локальной функции
    }
    
    // Вызов локальной функции
    LocalFunction(12);

    //переменные, инструкции метода
}

Здесь CoveringMethod()– это так называемый охватывающий метод. Внутри охватывающего метода объявляется локальная функция LocalFunction(), которая, для примера, принимает целочисленный параметр. Локальная функция вызывается внутри охватывающего метода и может располагаться в любом его месте, а также содержать любое количество параметров.

Преимущества локальных функций в C#

Использование локальных функций имеет ряд преимуществ, которые мы рассмотрим на нескольких примере.

Улучшение читаемости кода и локализация области видимости

Рассмотрим пример, код которого мы уже достаточно долго, в той или иной мере, используем в наших приложениях:

Console.WriteLine($"Результат вычислений: {Sum()}");

int Sum()
{
    Console.Write("Введите первое целое число: ");
    int number_1 = int.Parse(Console.ReadLine());

    Console.Write("Введите второе целое число: ");
    int number_2 = int.Parse(Console.ReadLine());
    
    return number_1 + number_2;
}

Метод Sum()суммирует два числа, которые вводит пользователь. В этом методе можно увидеть повторение действий – запрос пользователю -> чтение строки -> преобразование строки в число. Мы можем определить эти действия в методе, как локальную функцию:

int Sum()
{
    int RequestNumber(string requestText)
    {
        Console.Write("Введите первое целое число: ");
        return int.Parse(Console.ReadLine());
    }

    int number_1 = RequestNumber("Введите первое целое число: ");
    int number_2 = RequestNumber("Введите второе целое число: "); 
    
    return number_1 + number_2;
}

RequestNumber()– это локальная функция, которая выполняет одну задачу – запрашивает у пользователя число. При этом, функция видна только в методе Sum(), то есть вот такая попытка вызова локальной функции приведет к ошибке:

int num = RequestNumber("Введите число"); //ошибка CS0103 Имя "RequestNumber" не существует в текущем контексте.

Console.WriteLine($"Результат вычислений: {Sum()}");

int Sum()
{
    int RequestNumber(string requestText)
    {
        Console.Write("Введите первое целое число: ");
        return int.Parse(Console.ReadLine());
    }

    int number_1 = RequestNumber("Введите первое целое число: ");
    int number_2 = RequestNumber("Введите второе целое число: "); 
    
    return number_1 + number_2;
}

Возможность использования переменных из охватывающего метода

Локальная функция не видна за пределами охватывающего метода, однако сама она может получать доступ к переменным этого метода. Например,

int Sum()
{
    int errors;
    int number_1 = RequestNumber("Введите первое целое число: ");
    Console.WriteLine($"При вводе первого числа допущено {errors} ошибок");

    int number_2 = RequestNumber("Введите второе целое число: ");
    Console.WriteLine($"При вводе вторго числа допущено {errors} ошибок");


    int RequestNumber(string requestText)
    {
        errors = 0;
        bool isDone = false;
        int num = 0;
        while (isDone == false)
        {
            Console.Write(requestText);
            isDone = int.TryParse(Console.ReadLine(), out num);
            if (isDone == false)
                errors++;
        }
        return num;
    }

    return number_1 + number_2;
}

Здесь локальная функция получает доступ к переменной из охватывающего метода

Когда использовать локальные функции

Использовать локальные функции оправданно в следующих случаях:

  • когда необходимо разбить сложный метод на логические части 
  • когда необходимо повторное использования кода внутри метода
  • если локальная функция поможет улучшить читаемость кода
  • кода необходимо скрыть какую-либо логику программы от окружения

В любом случае, также можно отметить, что локальная функция – это один из множества возможностей организации кода в C# и не стоит увлекаться этой возможностью без надобности.

Подведем итог

Локальные функции определяются внутри другого метода и могут использовать параметры и переменные из охватывающего метода. Локальные функции могут улучшить читаемость кода и помогают, при необходимости, скрыть логику работы от окружения.

Домашнее задание №19

Напишите программу для вычисления факториала с использованием локальной функции.