2008-10-31 12 views
9

Eksperymentuję z wywoływaniem funkcji delegatów z tablicy delegatów. Udało mi się utworzyć tablicę uczestników, ale jak mogę połączyć się z delegatem?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: Powodem tablicy jest to, że muszę zadzwonić do funkcji delegata przez indeks, ile potrzeba. Nie są uruchamiane w odpowiedzi na zdarzenie. W moim kodzie widzę krytyczny (głupi) błąd, ponieważ próbowałem wykonać funkcję delegata używając typu pd [] zamiast nazwy tablicy (delegatów).

Odpowiedz

14

Jeśli wszystkie są tego samego typu, dlaczego nie połączyć ich w jednego uczestnika multiemisji?

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

... 
pd(); 
+0

Jednym z powodów, dla których nie należy indywidualnie zarządzać wyjątkami rzucanymi przez któregokolwiek z delegatów, a nie tylko łapanie pierwszego. –

+0

Zgodnie z moją edycją delegatów nie są wykonywane w odpowiedzi na zdarzenie, ale wywoływane indywidualnie przy użyciu indeksu w tablicy. – pro3carp3

+0

@jacob_c - tak, jeśli naprawdę chcesz :) @ pro3carp3 - w takim przypadku wystarczy uzyskać dostęp do indeksu zgodnie z normą dla tablicy. Nie ma w tym nic szczególnego, jako delegata. –

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

Technicznie, które powinny być MyClass.pd [0](). pd jest typem, a MyClass.pd jest statycznym członkiem MyClass. –

+0

Dlaczego nie łączysz razem les PD! –

7

w .NET, każdy delegat jest w rzeczywistości faktycznie „multicast” delegat (dziedziczy z tym wbudowanym w klasie bazowej), a więc zawiera wewnętrzną listę połączeń, które mogą zawierać dowolną liczbę delegatów docelowych.

Dostęp do tej listy można uzyskać, wywołując metodę GetInvocationList() na samym uczestniku. Ta metoda zwraca tablicę Delegatów ...

Jedynym ograniczeniem jest to, że wszyscy delegaci w obrębie połączonej listy danego delegata muszą mieć ten sam podpis (być tego samego typu delegata). Jeśli potrzebujesz, aby twoja kolekcja mogła zawierać delegatów różnych typów, musisz stworzyć własną listę lub klasę kolekcji.

Ale jeśli to jest w porządku, to może „wywołać” delegaci listy wywołania danego delegata jest tak:

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

To "deleguj", a nie "delegatów" –

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()); 
     } 


    } 

}