13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Delegates41Likewise, when you subscribe to or unsubscribe from an event, it looks like you’reus<strong>in</strong>g a field whose type is a delegate type, with the += and -= operators. Aga<strong>in</strong>,though, you’re actually call<strong>in</strong>g methods (add and remove 5 ). That’s all you can do witha pure event—subscribe to it (add an event handler) or unsubscribe from it (removean event handler). It’s up to the event methods to do someth<strong>in</strong>g useful—such as tak<strong>in</strong>gnotice of the event handlers you’re try<strong>in</strong>g to add and remove, and mak<strong>in</strong>g themavailable elsewhere with<strong>in</strong> the class.The reason for hav<strong>in</strong>g events <strong>in</strong> the first place is very much like the reason forhav<strong>in</strong>g properties—they add a layer of encapsulation. Just as you don’t want othercode to be able to set field values without the owner at least hav<strong>in</strong>g the option of validat<strong>in</strong>gthe new value, you often don’t want code outside a class to be able to arbitrarilychange (or call) the handlers for an event. Of course, a class can add methodsto give extra access—for <strong>in</strong>stance, to reset the list of handlers for an event, or toraise the event (<strong>in</strong> other words, call its event handlers). For example, Background-Worker.OnProgressChanged just calls the ProgressChanged event handlers. However,if you only expose the event itself, code outside the class only has the ability toadd and remove handlers.Field-like events make the implementation of all of this much simpler to look at—as<strong>in</strong>gle declaration and you’re done. The compiler turns the declaration <strong>in</strong>to both anevent with default add/remove implementations, and a private delegate type field.Code <strong>in</strong>side the class sees the field; code outside the class only sees the event. Thismakes it look as if you can <strong>in</strong>voke an event—but what you actually do to call the eventhandlers is <strong>in</strong>voke the delegate <strong>in</strong>stance stored <strong>in</strong> the field.The details of events are outside the scope of this chapter—events themselves haven’tchanged significantly <strong>in</strong> <strong>C#</strong> 2 or 3—but I wanted to draw attention to the differencebetween delegate <strong>in</strong>stances and events now, to prevent it caus<strong>in</strong>g confusion later on.2.1.4 Summary of delegatesSo, to summarize what we’ve covered on delegates:■■■■■■■Delegates allow behavior to be encapsulated.The declaration of a delegate type controls which methods can be used to createdelegate <strong>in</strong>stances.Creat<strong>in</strong>g a delegate <strong>in</strong>stance requires a method and (for <strong>in</strong>stance methods) atarget to call the method on.Delegate <strong>in</strong>stances are immutable.Delegate <strong>in</strong>stances each conta<strong>in</strong> an <strong>in</strong>vocation list—a list of actions.Delegate <strong>in</strong>stances can be comb<strong>in</strong>ed together and removed from each other.Events are not delegate <strong>in</strong>stances—they’re just add/remove method pairs(th<strong>in</strong>k property getters/setters).5These aren’t their names <strong>in</strong> the compiled code; otherwise you could only have one event per type. The compilercreates two methods with names that aren’t used elsewhere, and a special piece of metadata to let othertypes know that there’s an event with the given name, and what its add/remove methods are called.Licensed to Rhona Hadida

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!