Массив делегатов в C#

Я экспериментирую с вызовом функций делегата из массива делегатов. Мне удалось создать массив делегатов, но как мне вызвать делегата?

public delegate void pd();

public static class MyClass
{

    static void p1()
    {
        //...
    }

    static void p2 ()
    {
        //...
    }

    //...

    static pd[] delegates = new pd[] {

        new pd( MyClass.p1 ),
        new pd( MyClass.p2)
        /* ... */
    };
}

public class MainClass
{
    static void Main()
    {
        // Call pd[0]
        // Call pd[1]
    }
}

Обновлено: Причина создания массива в том, что мне нужно вызывать функции делегата по индексу по мере необходимости. Они не запускаются в ответ на событие. Я вижу критическую (глупую) ошибку в своем коде, поскольку я пытался выполнить функцию делегата, используя тип pd [], а не имя массива (делегатов).

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
21 549
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

public class MainClass
{
    static void Main()
    {
        pd[0]();
        pd[1]();
    }
}

Технически это должен быть MyClass.pd [0] (). pd - это тип, а MyClass.pd - статический член MyClass.

Mark Brackett 01.11.2008 01:41

Почему бы вам не объединить les PD вместе!

Jb Evain 26.10.2009 15:08
Ответ принят как подходящий

Если все они одного типа, почему бы просто не объединить их в один многоадресный делегат?

static pd delegateInstance = new pd(MyClass.p1) + new pd(MyClass.p2) ...;

...
pd();

Одна из причин не делать этого - индивидуально обрабатывать исключения, создаваемые любым из делегатов, а не просто перехватывать первое.

Jacob Carpenter 01.11.2008 03:12

Согласно моему редактированию, делегаты не выполняются в ответ на событие, а вызываются индивидуально с использованием индекса в массиве.

pro3carp3 01.11.2008 06:07

@jacob_c - да, если вы действительно хотите :) @ pro3carp3 - в этом случае вам просто нужно получить к нему доступ по индексу, как обычно для массива. Нет ничего особенного в том, чтобы быть здесь делегатом.

Jon Skeet 01.11.2008 10:22

Спасибо, Джон. Я сделал глупую ошибку и подумал, что чего-то не хватает.

pro3carp3 02.11.2008 02:17

В .Net любой делегат фактически является делегатом «многоадресной рассылки» (он наследуется от этого встроенного базового класса) и, следовательно, содержит внутренний связанный список, который может содержать любое количество целевых делегатов.

Вы можете получить доступ к этому списку, вызвав метод GetInvocationList () для самого делегата. Этот метод возвращает массив делегатов ...

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

Но если это нормально, то вы можете «вызвать» делегатов в списке вызовов данного делегата следующим образом:

public delegate void MessageArrivedHandler(MessageBase msg);
public class MyClass
{
     public event MessageArrivedHandler MessageArrivedClientHandler;   

     public void CallEachDelegate(MessageBase msg)
     {
          if (MessageArrivedClientHandler == null)
              return;
          Delegate[] clientList = MessageArrivedClientHandler.GetInvocationList();
          foreach (Delegate d in clientList)
          {
              if (d is MessageArrivedHandler)
                  (d as MessageArrivedHandler)(msg);
          }
     }
}
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        pd[0]();
        pd[1]();
    }

    public delegate void delegates();

    static delegates[] pd = new delegates[] 
                            { 
                               new delegates(MyClass.p1), 
                               new delegates(MyClass.p2) 
                            };

    public static class MyClass
    {
        public static void p1()
        {
            MessageBox.Show("1");
        }

        public static void p2()
        {
            MessageBox.Show("2");
        }
    }
}

Это «делегат», а не «делегаты»

Davide Andrea 18.01.2016 00:43
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        pd[0](1);
        pd[1](2);
    }

    public delegate void delegates(int par);
    static delegates[] pd = new delegates[] 
                                     { 
                                      new delegates(MyClass.p1), 
                                      new delegates(MyClass.p2) 
                                     };
    public static class MyClass
    {

        public static void p1(int par)
        {
            MessageBox.Show(par.ToString());
        }

        public static void p2(int par)
        {
            MessageBox.Show(par.ToString());
        }


    }

}

Другие вопросы по теме