The two functions are vaguely similar (both are designed to perform some kind of dynamic dispatch), but cannot be compared directly.
Events should notify other objects that the object has passed into some kind of state transition . This is a language feature that embodies the Observer design pattern . This can be useful in many cases, but not always useful or desirable. This is a tool for completing certain tasks.
Virtual functions are used to create object-oriented polymorphism . They are the main building block of almost every design pattern and a lot of object-oriented design.
To try to compare them, I assume that you are trying to implement some form of observer pattern with any function. With this restriction in place, there is still no simple rule that you can refuse to decide what you should use. Instead, you will have to ask yourself questions such as:
- Who caused it: Will the action that initiates the transition of your state take place internally or will it be called from the outside?
If this is called internally, you can use an event or a virtual method. If this is called externally, you should use a virtual method.
- Who cares: If the class that defines the state processes the consequences of the state transition or should it handle the outer class?
If the class to which the state belongs must handle the transition, then it must be a virtual method. If a single class needs to respond to the transition, this should be an event.
- How many handlers do I need: Do you always need one handler to respond to a state transition, or do you need a lot?
If you need it, then using a virtual method or event may be acceptable. If you need a lot, then it will be much easier to use the event.
- I know which handler I want at compile time: Do I bind to one well-known handler or bind to unknown handlers, possibly changing them over time?
If you need your handlers to change, you should use events. If you have only one handler that is known at compile time, you can use the virtual method.
- How much should my code be paired: Does your handler code use a derived class of your source type or belongs to it somewhere else?
If it belongs to a derived class, you need a virtual method. If it belongs elsewhere, you need an event.
As you can see, the answers will largely depend on your specific problem area and object architecture. Good design is not something that magically falls into your lap through some checklist. You have to think about it, a lot :)
Edit:
It may not be directly applicable to C # events, but it may be useful to take an example from existing work. Here is a short article I just found (answering another question) on Java design alternatives for creating templates: http://csis.pace.edu/~bergin/patterns/event.html