views:

872

answers:

3
+2  Q: 

Delegate Array

I am experimenting with calling delegate functions from a delegate array. I've been able to create the array of delegates, but how do I call the delegate?

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: The reason for the array is that I need to call the delegate functions by an index as needed. They are not run in response to an event. I see a critical (stupid) error in my code as I had tried to execute the delegate function using the pd[] type rather than the name of the array (delegates).

+4  A: 
public class MainClass
{
    static void Main()
    {
        pd[0]();
        pd[1]();
    }
}
Romain Verdier
Technically, that should be MyClass.pd[0](). pd is a type, and MyClass.pd is static member of MyClass.
Mark Brackett
Why don't you combine les PD together!
Jb Evain
+6  A: 

If they're all the same type, why not just combine them into a single multicast delegate?

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

...
pd();
Jon Skeet
One reason not to would be to individually handle exceptions thrown by any of the delegates, rather than just catching the first.
Jacob Carpenter
As per my edit, the delegates are not executed in response to an event, but called individually using an index in to the array.
pro3carp3
@jacob_c - yes, if you actually want to :)@pro3carp3 - in that case you just need to access it by index as per normal for an array. There's nothing special about it being a delegate here.
Jon Skeet
Thanks, Jon. I made a stupid error and thought I was missing something.
pro3carp3
+2  A: 

In .Net, any delegate is in fact actually a "multicast" delegate (it inherits from this buily-in base class), and therefore contains an internal linked list which can contain any number of target delegates.

You can access this list by calling the method GetInvocationList() on the delegate itself. This method returns an array of Delegates...

The only restriction is that all the delegates inside of a given delegate's linked list must have the same signature, (be of the same delegate type). If you need your collection to be able to contain delegates of disparate types, then you need to construct your own list or collection class.

But if this is ok, then you can "call" the delegates in a given delegate's invocation list like this:

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);
          }
     }
}
Charles Bretana