When a class can't (or should not) do something, then events or delegates could be a solution.
say
class President
Event AskedQuestion(QuestionEventArgs)
Delegate GetAnswerToQuestion
class Scientist
AnswerToQuestion()
// delegate approach
myPresident.GetAnswerToQuestion = AddressOf myScientist.AnswerToQuestion
// called once myPresident need it
// event approach
myScientist.AnswerToQuestion(questionEventArgs) Handles President.AskedQuestion
{
// executed once president asked a question
}
Here in the delegate approach Scientist method is used directly by the President class, in the event one President raises a question, and the Scientist react to it with an answer.
In the .NET Framework code I didn't observe, however the direct use of delegates. Is it wrong to use it directly, and if, why?
Is it wrong to use it directly, and if, why?
No, it's not wrong.
Here's how I think about it. Delegate fields are to events as string fields are to properties. That is, you might have:
class Car
{
private string modelName;
public string ModelName { get { return this.modelName; } }
...
The model name is logically a property of a car. When someone asks you what kind of car you drive and you say "a Ford Focus", you are describing a property of the car. You do not think of "Ford Focus" as being a "field" or a "string", you think of it as being the name of a kind of car. In the computer program, the string field is just the implementation detail of how the name is stored. The property could be a string, or it could be an enum, or whatever; the point is that logically, cars have model names, not string fields.
Events and delegates are the same way. A car can have an "explode" event (perhaps you are writing a video game!) and the explode event is implemented by a field of delegate type. Exploding is something the car logically does; the delegate field is the mechanism by which the event is implemented.
So is it "wrong" to use delegates directly? No, of course not. No more than it is "wrong" to use strings directly. Sometimes you need to manipulate strings that are not properties, and sometimes you need to manipulate delegates that are not events.
The trick is to write code that clearly separates the mechanical processes from the business processes. If you find that you're mixing a lot of string logic with your property logic, or mixing a lot of delegate manipulation with your events, then you might consider trying to separate the mechanism code from the business code a bit more, so that it is easier to see which is which.
There is plenty of use of delegates in the framework. LINQ is a clear example of this:
var result = someCollection.Where(input => input.MatchesSomeCriteria);
Where
takes a delegate with a specific signature which is invoked in order to determine whether to include an item in the result or not. The most common use is the lamba approach as shown above, but you can just as well pass a method:
string[] nums = new[]{ "1", "2", "3"};
int sum = nums.Select(int.Parse).Sum();
int.Parse
matches the required delegate signature that Select
expects in this case (Func<string,int>
), so it will be invoked for each of the strings in nums
.
Typically when delegates are used directly, they are taken as input to method calls that will consume them. There are some places where they are part of the consumers state though (HttpListener
for instance has a few properties that are of delegate types), but they are not that many.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With