This chapter began with a discussion of delegates and their use as method pointers and callbacks. Next, it discussed the full potential of a delegate within the observer pattern. Now that you have described events, it is worth mentioning that in general, method pointers are the only cases where it is advisable to work with a delegate variable outside of the context of an event. In other words, given the additional encapsulation features of an event and the ability to customize the implementation when necessary, the best practice is always to use events for the observer pattern.
This chapter also introduced two syntaxes for creating delegate instances. C# 2.0 allows the assigning of delegates directly, by just using the method's name. Prior to this, it was necessary to explicitly instantiate delegates using the new operator. Throughout the remainder of the book, I will show only the C# 2.0 syntax. (This will cause some of the remaining code not to compile on version 1.0 compilers without modification to use explicit delegate instantiation.)
It may take a little practice to be able to code delegates and events from scratch without sample code. However, they are a critical foundation to the asynchronous, multithreaded coding of the next chapter.