C#: Делегаты

Spread the love

In C#, a delegate is a type that represents a reference to a method. It allows you to treat methods as first-class objects, enabling you to pass methods as parameters to other methods, store them in variables, and invoke them dynamically.

Delegates provide a way to achieve “function pointers” or “callbacks” in C#, making it possible to implement powerful and flexible event handling, callback mechanisms, and more.

Declaration of a delegate:

“`csharp

delegate return_type DelegateName(parameter_list);

“`

100000R, 12%, 1 year

– `return_type`: The return type of the method that the delegate can reference.

– `DelegateName`: The name of the delegate type.

– `parameter_list`: The list of parameters that the referenced method should take.

Creating a delegate instance and invoking the referenced method:

“`csharp

// Declare a delegate type

delegate void MyDelegate(string message);

// Define a method that matches the delegate signature

static void PrintMessage(string message)

{

    Console.WriteLine(message);

}

static void Main()

{

    // Create an instance of the delegate

    MyDelegate delegateInstance = PrintMessage;

    // Invoke the referenced method using the delegate

    delegateInstance(“Hello, delegates!”);

}

“`

In this example, we declare a delegate type `MyDelegate` that can reference methods with a `void` return type and a single `string` parameter. We define a method `PrintMessage` that matches the delegate’s signature. Then, we create an instance of the delegate, `delegateInstance`, and assign the `PrintMessage` method to it. Finally, we invoke the referenced method using the delegate, and it prints “Hello, delegates!” to the console.

Delegates are commonly used for event handling in C# and play a vital role in the implementation of event-driven programming. They provide a flexible way to decouple the source of an event from the code that handles the event, allowing for more maintainable and extensible code.

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

Делегаты предоставляют способ получения “указателей на функции” или “обратных вызовов” в C#, позволяя реализовать мощную и гибкую обработку событий, механизмы обратного вызова и многое другое.

Объявление делегата:

“`csharp

delegate return_type DelegateName(parameter_list);

“`

– `return_type`: Возвращаемый тип метода, на который может ссылаться делегат.

– `DelegateName`: Имя типа делегата.

– `parameter_list`: Список параметров, которые должен принимать указанный метод.

Создаём экземпляр делегата и вызоваем метод, на который ссылается ссылка:

“`csharp

// Declare a delegate type

delegate void MyDelegate(string message);

// Define a method that matches the delegate signature

static void PrintMessage(string message)

{

    Console.WriteLine(message);

}

static void Main()

{

    // Create an instance of the delegate

    MyDelegate delegateInstance = PrintMessage;

    // Invoke the referenced method using the delegate

    delegateInstance(“Hello, delegates!”);

}

“`

В этом примере мы объявляем делегат типа `MyDelegate`, который может ссылаться на методы с типом возвращаемого значения `void` и единственным параметром `string`. Мы определяем метод `printMessage`, который соответствует подписи делегата. Затем мы создаем экземпляр делегата, `delegate Instance`, и назначаем ему метод `printMessage`. Наконец, мы вызываем указанный метод с помощью делегата, и он выводит “Hello, delegates!” на консоль.

Делегаты обычно используются для обработки событий в C# и играют жизненно важную роль в реализации событийно-ориентированного программирования. Они обеспечивают гибкий способ отделения источника события от кода, который обрабатывает это событие, что позволяет создавать более удобный в обслуживании и расширяемый код.

                            Action

In C#, `Action` is a built-in delegate type defined in the `System` namespace. It is a generic delegate that can reference methods with zero to sixteen input parameters, but it does not return a value (i.e., has a `void` return type). `Action` is commonly used when you need to represent a method that performs an action without returning a result.

The `Action` delegate can be useful in scenarios where you want to pass a method as a parameter to another method, such as in LINQ queries or for asynchronous operations.

Syntax for `Action` delegates:

“`csharp

public delegate void Action();

public delegate void Action<in T>(T obj);

public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);

// …

public delegate void Action<in T1, in T2, …, in T16>(T1 arg1, T2 arg2, …, T16 arg16);

“`

Here are some examples of how you can use `Action` delegates:

1. A simple `Action` delegate without parameters:

“`csharp

using System;

class Program

{

    static void HelloWorld()

    {

        Console.WriteLine(“Hello, World!”);

    }

    static void Main()

    {

        Action action = HelloWorld;

        action(); // Outputs: Hello, World!

    }

}

“`

2. An `Action` delegate with one parameter:

“`csharp

using System;

class Program

{

    static void PrintMessage(string message)

    {

        Console.WriteLine(message);

    }

    static void Main()

    {

        Action<string> printAction = PrintMessage;

        printAction(“Hello, delegates!”); // Outputs: Hello, delegates!

    }

}

“`

3. An `Action` delegate with multiple parameters:

“`csharp

using System;

class Program

{

    static void SumAndPrint(int a, int b)

    {

        int sum = a + b;

        Console.WriteLine($”Sum: {sum}”);

    }

    static void Main()

    {

        Action<int, int> sumAction = SumAndPrint;

        sumAction(5, 7); // Outputs: Sum: 12

    }

}

“`

In each example, we declare an `Action` delegate and assign a method to it. Then, we invoke the method through the `Action` delegate. The `Action` delegate provides a convenient way to reference and invoke methods with different numbers of parameters, making it more flexible and expressive in various scenarios.

В C# Action – это встроенный тип делегата, определенный в системном пространстве имен. Это универсальный делегат, который может ссылаться на методы с нулем до шестнадцати входных параметров, но он не возвращает значение (т.е. имеет возвращаемый тип void). Действие обычно используется, когда вам нужно представить метод, который выполняет действие без возврата результата.

Делегат действия может быть полезен в сценариях, где вы хотите передать метод в качестве параметра другому методу, например, в запросах LINQ или для асинхронных операций.

Синтаксис для делегатов Action:

“`csharp

public delegate void Action();

public delegate void Action<in T>(T obj);

public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);

// …

public delegate void Action<in T1, in T2, …, in T16>(T1 arg1, T2 arg2, …, T16 arg16);

“`

Вот несколько примеров того, как можнор использовать делегаты `Action`:

1. Простой делегат `Action` без параметров:

“`csharp

using System;

class Program

{

    static void HelloWorld()

    {

        Console.WriteLine(“Hello, World!”);

    }

    static void Main()

    {

        Action action = HelloWorld;

        action(); // Outputs: Hello, World!

    }

}

“`

2. Делегат `Action` с одним параметром:

“`csharp

using System;

class Program

{

    static void PrintMessage(string message)

    {

        Console.WriteLine(message);

    }

    static void Main()

    {

        Action<string> printAction = PrintMessage;

        printAction(“Hello, delegates!”); // Outputs: Hello, delegates!

    }

}

“`

3. Делегат `Action` с несколькими параметрами:

“`csharp

using System;

class Program

{

    static void SumAndPrint(int a, int b)

    {

        int sum = a + b;

        Console.WriteLine($”Sum: {sum}”);

    }

    static void Main()

    {

        Action<int, int> sumAction = SumAndPrint;

        sumAction(5, 7); // Outputs: Sum: 12

    }

}

“`

В каждом примере мы объявляем делегат `Action` и назначаем ему метод. Затем мы вызываем метод через делегат `Action`. Делегат `Action` предоставляет удобный способ ссылаться на методы с различным количеством параметров и вызывать их, что делает его более гибким и выразительным в различных сценариях.

                            Func

In C#, `Func` is another built-in delegate type defined in the `System` namespace. Unlike `Action`, `Func` is a generic delegate that can reference methods with zero to sixteen input parameters and returns a value of a specified type.

The last type parameter in a `Func` delegate represents the return type of the referenced method.

Syntax for `Func` delegates:

“`csharp

public delegate TResult Func<out TResult>();

public delegate TResult Func<in T, out TResult>(T obj);

public delegate TResult Func<in T1, in T2, …, in T16, out TResult>(T1 arg1, T2 arg2, …, T16 arg16);

“`

Here are some examples of how you can use `Func` delegates:

1. A simple `Func` delegate with no parameters and a return value:

“`csharp

using System;

class Program

{

    static int GetRandomNumber()

    {

        Random random = new Random();

        return random.Next(1, 101);

    }

    static void Main()

    {

        Func<int> getRandomNumberFunc = GetRandomNumber;

        int randomNum = getRandomNumberFunc();

        Console.WriteLine($”Random number: {randomNum}”);

    }

}

“`

2. A `Func` delegate with parameters and a return value:

“`csharp

using System;

class Program

{

    static int Add(int a, int b)

    {

        return a + b;

    }

    static void Main()

    {

        Func<int, int, int> addFunc = Add;

        int result = addFunc(5, 7);

        Console.WriteLine($”Result: {result}”); // Outputs: Result: 12

    }

}

“`

3. A `Func` delegate returning a string:

“`csharp

using System;

class Program

{

    static string Greet(string name)

    {

        return $”Hello, {name}!”;

    }

    static void Main()

    {

        Func<string, string> greetFunc = Greet;

        string greeting = greetFunc(“John”);

        Console.WriteLine(greeting); // Outputs: Hello, John!

    }

}

“`

In each example, we declare a `Func` delegate with the appropriate number of input parameters and the return type. We then assign a method to the `Func` delegate and invoke the method through the delegate, receiving the return value.

The `Func` delegate is particularly useful when you need to pass a method as a parameter to another method and retrieve a result from that method. It provides a convenient way to represent and use methods with various signatures and return types in a generic and flexible manner.

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

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

Синтаксис для делегатов Func:

“`csharp

public delegate TResult Func<out TResult>();

public delegate TResult Func<in T, out TResult>(T obj);

public delegate TResult Func<in T1, in T2, …, in T16, out TResult>(T1 arg1, T2 arg2, …, T16 arg16);

“`

Вот несколько примеров того, как вы можете использовать делегаты `Func`:

1. Простой делегат `Func` без параметров и возвращаемого значения:

“`csharp

using System;

class Program

{

    static int GetRandomNumber()

    {

        Random random = new Random();

        return random.Next(1, 101);

    }

    static void Main()

    {

        Func<int> getRandomNumberFunc = GetRandomNumber;

        int randomNum = getRandomNumberFunc();

        Console.WriteLine($”Random number: {randomNum}”);

    }

}

“`

2. Делегат `Func` с параметрами и возвращаемым значением:

“`csharp

using System;

class Program

{

    static int Add(int a, int b)

    {

        return a + b;

    }

    static void Main()

    {

        Func<int, int, int> addFunc = Add;

        int result = addFunc(5, 7);

        Console.WriteLine($”Result: {result}”); // Outputs: Result: 12

    }

}

“`

3. Делегат `Func`, возвращающий строку:

“`csharp

using System;

class Program

{

    static string Greet(string name)

    {

        return $”Hello, {name}!”;

    }

    static void Main()

    {

        Func<string, string> greetFunc = Greet;

        string greeting = greetFunc(“John”);

        Console.WriteLine(greeting); // Outputs: Hello, John!

    }

}

“`

В каждом примере мы объявляем делегат `Func` с соответствующим количеством входных параметров и типом возвращаемого значения. Затем мы назначаем метод делегату `Func` и вызываем метод через делегат, получая возвращаемое значение.

Делегат `Func` особенно полезен, когда вам нужно передать метод в качестве параметра другому методу и получить результат из этого метода. Это обеспечивает удобный способ представления и использования методов с различными сигнатурами и типами возвращаемых данных универсальным и гибким способом.

                            Anonym Functions

In C#, anonymous functions are unnamed methods defined inline without a separate method declaration. They are useful when you need a small, short-lived function and don’t want to create a separate named method for it.

Anonymous functions can be used with delegate types like `Action` and `Func`, as well as with custom delegate types.

There are three types of anonymous functions in C#:

1. Lambda Expressions:

Lambda expressions are a concise way to define anonymous functions, especially for single-line functions. They have a compact syntax using the `=>` (lambda operator) and are often used with delegate types like `Action` and `Func`.

Example of using a lambda expression with `Action`:

“`csharp

using System;

class Program

{

    static void Main()

    {

        Action<string> printMessage = message => Console.WriteLine(message);

        printMessage(“Hello, lambda!”); // Outputs: Hello, lambda!

    }

}

“`

2. Anonymous Methods:

Anonymous methods are more expressive than lambda expressions and can have multiple statements. They don’t use the `=>` syntax and instead use the `delegate` keyword to specify the delegate type.

Example of using an anonymous method with `Action`:

“`csharp

using System;

class Program

{

    static void Main()

    {

        Action<string> printMessage = delegate(string message)

        {

            Console.WriteLine(message);

            Console.WriteLine(“This is an anonymous method.”);

        };

        printMessage(“Hello, anonymous method!”);

        // Outputs:

        // Hello, anonymous method!

        // This is an anonymous method.

    }

}

“`

3. Function (Method) Pointers:

C# allows you to use function pointers to refer to methods, similar to how you would use them in other programming languages like C and C++. This method of defining anonymous functions is less commonly used but can be useful in specific scenarios.

Example of using a function pointer with `Func`:

“`csharp

using System;

class Program

{

    static int Add(int a, int b)

    {

        return a + b;

    }

    static void Main()

    {

        Func<int, int, int> addFunc = Add;

        Console.WriteLine(addFunc(5, 7)); // Outputs: 12

    }

}

“`

Anonymous functions are often used in LINQ queries, event handlers, and other scenarios where you need a short, inline function without the overhead of declaring a separate named method. They improve code readability and maintainability by reducing the number of named methods with specific logic, especially for simple operations.

В C# Anonymous methods (анонимные функции) – это безымянные методы, определённые в строке без отдельного объявления метода. Они полезны, когда вам нужна небольшая, недолговечная функция, и вы не хотите создавать для неё отдельный именованный метод.

Anonymous methods можно использовать с типами делегатов, такими как Action и Func, а также с пользовательскими типами делегатов.

В C# существует три типа Anonymous methods:

1. Lambda Expressions (Лямбда-выражения):

Lambda Expressions – это краткий способ определения анонимных функций, особенно для однострочных функций. Они имеют компактный синтаксис, использующий => (лямбда-оператор), и часто используются с типами делегатов, такими как Action и Func.

Пример использования Lambda Expressions (лямбда-выражения) с Action:

“`csharp

using System;

class Program

{

    static void Main()

    {

        Action<string> printMessage = message => Console.WriteLine(message);

        printMessage(“Hello, lambda!”); // Outputs: Hello, lambda!

    }

}

“`

2. Anonymous Methods:

Anonymous methods (Анонимные методы) более выразительны, чем lambda expressions (лямбда-выражения), и могут содержать несколько инструкций. Они не используют синтаксис `=>` и вместо этого используют ключевое слово `delegate` для указания типа делегата lambda expressions and can have multiple statements.

Пример использования Anonymous method with `Action`:

“`csharp

using System;

class Program

{

    static void Main()

    {

        Action<string> printMessage = delegate(string message)

        {

            Console.WriteLine(message);

            Console.WriteLine(“This is an anonymous method.”);

        };

        printMessage(“Hello, anonymous method!”);

        // Outputs:

        // Hello, anonymous method!

        // This is an anonymous method.

    }

}

“`

3. Указатели на функцию (метод):

C# позволяет вам использовать указатели на функции для ссылки на методы, аналогично тому, как вы использовали бы их в других языках программирования, таких как C и C++. Этот метод определения анонимных функций используется реже, но может быть полезен в конкретных сценариях.

Пример использования указателя на функцию с `Func`:

“`csharp

using System;

class Program

{

    static int Add(int a, int b)

    {

        return a + b;

    }

    static void Main()

    {

        Func<int, int, int> addFunc = Add;

        Console.WriteLine(addFunc(5, 7)); // Outputs: 12

    }

}

“`

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

Схема Делегаты

Spread the love

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