2008-10-31 3 views
9

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

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] 
    } 
} 

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

ответ

14

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

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

... 
pd(); 
+0

Одна из причин, по которой не было бы индивидуально обрабатывать исключения, брошенные кем-либо из делегатов, а не просто ловить первое. – 2008-11-01 00:12:15

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

Технически, это должно быть MyClass.pd [0](). pd является типом, а MyClass.pd является статическим членом MyClass. – 2008-10-31 22:41:11

+0

Почему бы вам не объединить les PD вместе! – 2009-10-26 12:08:39

7

В .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); 
      } 
    } 
} 
3
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"); 
     } 
    } 
} 
0
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()); 
     } 


    } 

}