C# Programming

Мастерство передачи методов в C#

Spread the love

C# позволяет передавать методы в качестве параметров функциям, значительно повышая гибкость и повторное использование кода. Эта возможность имеет решающее значение для реализации обратных вызовов, обработчиков событий и стратегических шаблонов, где поведение во время выполнения определяет конкретное действие. В этой статье рассматриваются различные подходы к достижению этого, с упором на пользовательские делегаты, Func<> и Action<>.

Оглавление

Использование пользовательских делегатов для передачи методов в качестве параметров

Делегаты в C# служат указателями на функции с проверкой типов. Создание пользовательского делегата обеспечивает точный контроль и ясность, когда сигнатура метода отличается от встроенных делегатов Func<> или Action<>. Рассмотрим функцию, выполняющую операцию над числом и затем отображающую результат, где сама операция является параметром.


// Определение пользовательского делегата
public delegate double MathOperation(double x);

public class Example
{
    public static void PerformOperationAndPrint(double num, MathOperation operation)
    {
        double result = operation(num);
        Console.WriteLine($"Result: {result}");
    }

    public static double Square(double x) => x * x;
    public static double Cube(double x) => x * x * x;

    public static void Main(string[] args)
    {
        PerformOperationAndPrint(5, Square); // Output: Result: 25
        PerformOperationAndPrint(5, Cube);  // Output: Result: 125
    }
}

MathOperation выступает в роли делегата, представляющего метод, принимающий double и возвращающий double. PerformOperationAndPrint принимает этот делегат, позволяя использовать Square, Cube или любой соответствующий метод.

Использование делегата Func<>

Func<> — это универсальный делегат, представляющий метод с нулем или более входными параметрами и возвращаемым значением. Его встроенный характер упрощает многие сценарии. Давайте переработаем предыдущий пример:


public class Example
{
    public static void PerformOperationAndPrint(double num, Func<double, double> operation)
    {
        double result = operation(num);
        Console.WriteLine($"Result: {result}");
    }

    public static double Square(double x) => x * x;
    public static double Cube(double x) => x * x * x;

    public static void Main(string[] args)
    {
        PerformOperationAndPrint(5, Square); // Output: Result: 25
        PerformOperationAndPrint(5, Cube);  // Output: Result: 125
    }
}

Это достигает того же результата с меньшим количеством кода. Func<double, double> указывает метод, принимающий double и возвращающий double. Универсальные параметры типа адаптируются к различным сигнатурам методов (например, Func<int, string>).

Использование делегата Action<>

Action<> — это универсальный делегат для методов с нулем или более входными параметрами и типом возвращаемого значения void (без возвращаемого значения). Используйте его, когда методы не возвращают значения.


public class Example
{
    public static void PerformAction(string message, Action<string> action)
    {
        action(message);
    }

    public static void PrintMessage(string msg) => Console.WriteLine(msg);
    public static void PrintMessageToUpper(string msg) => Console.WriteLine(msg.ToUpper());

    public static void Main(string[] args)
    {
        PerformAction("Hello, world!", PrintMessage);       // Output: Hello, world!
        PerformAction("Hello, world!", PrintMessageToUpper); // Output: HELLO, WORLD!
    }
}

Action<string> представляет метод, принимающий строку и ничего не возвращающий. PerformAction использует это для выполнения различных действий печати.

Заключение

Передача методов в качестве параметров — мощная функция C#. Пользовательские делегаты обеспечивают максимальный контроль, в то время как Func<> и Action<> предоставляют удобные встроенные решения. Лучший подход зависит от конкретных требований вашего приложения. Освоение этих методов является ключом к написанию более адаптируемого и поддерживаемого кода C#.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *