I've been trying to learn about C# delegates and events but man,m i seriously cant get my head around it. :-(
Man, I feel your pain. It took me forever for delegates to click, and I never found any of the online examples to be helpful. So I will try to help you.
OK, so I was recently working on a project that involved pathfinding. In an earlier project, I just gave every tile a "traversability" property, so when the pathfinding algorithm got to a tile, it would just look at that property and add it to the list of possible path nodes or not. For this project, I wanted to be able to find a path with arbitrary traversability rules. For example, if I specifically wanted a path that sticks to the edge of a landmass, I would want only land tiles that are touching water to be considered traversable in the algorithm.
Delegates were the answer!
With delegates I can pass, as a parameter, an arbitrary method into my pathfinding method. This arbitrary method would need to itself take a parameter: a tile that could be judged traversable or not. It would then need to return a bool indicating traversability of that tile.
But when defining my pathfinder method with parameters, I need to tell it what
type those parameters are. So I needed that tile-in-bool-out out method to have a type before I could pass it into my pathfinder as a parameter. The type can't just be "delegate" because then there would be no telling what kinds of methods got passed in and C# would cry. So what I had to do is use the delegate keyword to
define a type for my traversability-determining method.
so in PathFinder.cs, before I define the class PathFinder, I put the following:
Code:
public delegate bool PathFinderDelegate(Tile t);
What this does is define a type called PathFinderDelegate that can be passed into a method as a parameter. This type is defined to be methods that take a Tile as a parameter and return a bool.
My previous FindPath method looked like this:
Code:
public List<Tile> FindPath(Tile startTile, Tile endTile)
{
//blah
//...
//blah
//...
if (someTile.IsTraversable()) //I want to know if someTile is traversable
{
DoStuff();
}
//...
}
But now I can define my FindPath method thusly:
Code:
public List<Tile> FindPath(Tile startTile, Tile endTile, PathFinderDelegate traversableCondition)
{
//blah
//...
//blah
//...
if (traversableCondition(someTile)) //I want to know if someTile meets the arbitrary traversability condition
{
DoStuff();
}
//...
}
So now my pathfinder is totally set up to take arbitrary traversability rules. Now I just have to call FindPath and give it a traversability rule. There is more than one way to do this, but the way I generally did it in my project was thus (in this example, I want a path that hugs the edge of a land mass):
Code:
List<Tile> coastalPath = PathFinder.FindPath(
startTile,
endTile,
delegate (Tile t) { return t.IsLand() && t.IsTouchingWater(); }
);
The delegate keyword used there is a bit confusing because it looks like the keyword I used to define that type earlier. In this case the delegate keyword is used to indicate an anonymous method, which is just a nameless method that you define in-line like I did here. But the important thing is that this anonymous method takes a Tile parameter, and returns a bool.
I hope this was at all helpful - If not, well, I understand, I've been there. Let me know if you need a clarification on anything! I'm just now starting to use events, but once you're comfy with delegates, events are easy.