Getting started with delegates–part IV

Ah, the joy! Almost in vacations, but still one day to go!

We’ve already covered a lot of ground in this delegate series. As we’ve seen, creating a delegate is rather easy: we just need to provide a compatible method and pass it to the delegate constructor which is being initialized. However, there might be times where you don’t have all the required information for creating a new delegate at compile time. Fortunately, our job is not that complicated in these (rare!) cases because the Delegate type introduces several overloads of the CreateDelegate method which helps us in creating new delegate instances at runtime. To illustrate this strategy, we’ll reuse our old Logger delegate definition:

public delegate void Logger( String info );

And now, we’re ready to create dynamic delegates…Let’s start with creating a new delegate for the following static method:

public static class Holder {
    public static void DoIt(String info) {
        Console.WriteLine( "from static: " + info );
    }
}

And now, here’s how we resort to CreateDelegate to create a new delegate which “wraps” the DoIt static method:

var methodInfo = typeof( Holder ).GetMethod( "DoIt",
       BindingFlags.Static | BindingFlags.Public );
var aux = Delegate.CreateDelegate( typeof( Logger ), methodInfo );

After running the previous code, aux references a Delegate instance. At this point, we have two options: we can cast aux to the correct type (not something you’d be able to do when you’re creating delegates like this) or we can rely on Delegate’s DynamicInvoke method:

aux.DynamicInvoke( "Hello!" );

DynamicInvoke ends up calling the delegate’s callback method while sending it the arguments it received. Notice that DynamicInvoce will always ensure that the passed in arguments are compatible with the ones expected by the callback method (if they aren’t, you’ll end up with an exception). As you’re probably expecting, there are also other overloads which you can use for creating delegates that wrap instance methods. Suppose we modify our Holder class so that it looks like this:

public class Holder {
    public void DoIt(String info) {
        Console.WriteLine( "from instance: " + info );
    }
}

And here’s how you can create a new delegate dynamically:

var methodInfo = typeof( Holder ).GetMethod( "DoIt",
       BindingFlags.Instance | BindingFlags.Public );
var aux = Delegate.CreateDelegate( typeof( Logger ), new Holder(), methodInfo );

And now you can invoke the delegate by executing the DynamicInvoke method like we did before.

Before ending, there’s still time to say that you shouldn’t really use the CreateDelegate overloads which use strings (instead of MethodInfo instances) because there’s a chance of getting an ambiguous binding (and that might lead to unpredicted results).

And that’s it for now. Stay tuned for more.

Advertisements

~ by Luis Abreu on August 3, 2011.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: