Когда вы говорите «они используются, если вы не хотите вызывать метод напрямую, а не оставляете место для пользовательской реализации», вы заставляете меня думать, что вы можете не полностью понять разницу между простым делегатом и событием. Здесь очень упрощенно, но вот краткое объяснение ...
Делегаты - это способ позволить тому, кто пишет код, использовать ваш код для предоставления своего собственного метода. Как таковые, они не проходят через насос сообщений и происходят синхронно и т. Д.
События используют делегата, чтобы предоставить вам возможность ввести свой собственный код для ответа на событие. События проходят через насос сообщений и являются подходящими, когда есть что-то, на что вам нужно ответить, что может происходить в другом месте. Однако они будут происходить за пределами пути выполнения исполняемого в данный момент кода.
К счастью, большинство людей, кажется, понимают, когда использовать то или другое инстинктивно. Опять же, грубое упрощение здесь, но, надеюсь, достаточно для дальнейшего чтения.