You may already be familiar with the non-generic delegates. However, for the sake of cohesiveness and to better understand the value generics bring to delegates, it may be useful to first establish a clear view of the general role of delegates in the .NET platform. By first examining the basics of delegates, you'll have a better foundation for understanding how generics have been applied to enhance their overall functionality.
Fundamentally, a delegate is meant to serve as a type-safe reference to a method. When you declare a delegate, you are only declaring the signature of a method without any corresponding implementation. That delegate is given a name and can then be referenced like any other type. Now, whenever you declare a method with a signature that matches the signature of your delegate, that method (and its implementation) can be passed as a parameter to any method that references your delegate type. So, you could have three different methods that all match your delegate signature and, at run-time, pass any one of these methods as a parameter to another method that includes your delegate in its signature. This essentially gives you an alternative form of polymorphism.
That may still be a bit abstract. Here's a more concrete example to solidify this concept. Suppose you introduce the following delegate declaration, which serves as a delegate that is used to update Employee objects:
[VB code] Public Delegate Sub UpdateEmployee(ByVal val As Employee) ...