Simple answer: the code needing to perform the action doesn’t know the method to call when it’s written. You can only call the method directly if you know at compile-time which method to call, right? So if you want to abstract out the idea of “perform action X at the appropriate time” you need some representation of the action, so that the method calling the action doesn’t need to know the exact implementation ahead of time.
For example:
Enumerable.Selectin LINQ can’t know the projection you want to use unless you tell it- The author of
Buttondidn’t know what you want the action to be when the user clicks on it - If a new Thread only ever did one thing, it would be pretty boring…
It may help you to think of delegates as being like single-method interfaces, but with a lot of language syntax to make them easy to use, and funky support for asynchronous execution and multicasting.