There are seriously too many usefull situations to apply the usage of delegates to go and list them off -
I would say these are at the top of the usefulness list:
Creating a custom scope - so lets say you want to apply a method/action to a list of objects and apply locally scoped values into the body of the delegate but really don't need to add a bunch of additional variables to the scope of the entire class...
[STAThread]
public static void Main()
{
// Creating a custom window...
var win = new Form();
// opening an xml file...
var doc = new XmlDocument();
doc.Load("C:\\MyDoc.xml");
var root = doc.DocumentElement;
//Cycling through each of the nodes in the root element of the XML file
foreach (var child in root.ChildNodes.Cast<XmlElement>())
{
// Creating a reference to the node
var node = child;
var name = node.GetAttribute("name");
// Creating a new button
var button = new Button()
{
Dock = DockStyle.Top,
Text = name
};
// Giving the button's click handler a delegate that has access to
// the node that is associated with this itteration of the foreach
// loop. This would be difficult using an externally defined method
button.Click +=
delegate
{
var message = node.GetAttribute("message");
MessageBox.Show("The node named " + name + " had the message:\r\n" + message);
//Obviously you won't often be creating buttons like this - but you could very
//easily add actions to the Tags of a tree node or a custom class of your own.
};
// adding the button to the form
win.Controls.Add(button);
}
// showing the completed dynamic window
win.ShowDialog();
}
}
also - when used properly - delegates can make huge reductions in your code. Take for example this generic filter...
public class GenericObjectFilter
{
public TItem[] FilterObjects<TItem>(TItem[] items, Func<TItem, string> identifier, string[] include)
{
var results = new List<TItem>();
foreach (var item in items)
if (include.Contains(identifier(item)))
results.Add(item);
return results.ToArray();
}
}
This one filter can be used to filter literally any object in existence...
public class SomeClassA
{
public string ClassAName { get; set; }
}
public class SomeClassB
{
public string ClassBName { get; set; }
}
public class SomeClassC
{
public string ClassCName { get; set; }
}
static class Program
{
[STAThread]
public static void Main()
{
var filterStrings = new[] {"Aardvark", "Video", "Game"};
var collectionA = new SomeClassA[100];
var collectionB = new SomeClassB[100];
var collectionC = new SomeClassC[100];
var filter = new GenericObjectFilter();
var filteredA = filter.FilterObjects(
collectionA,
item => item.ClassAName,
filterStrings);
var filteredB = filter.FilterObjects(
collectionB,
item => item.ClassBName,
filterStrings);
var filteredC = filter.FilterObjects(
collectionC,
item => item.ClassCName,
filterStrings);
// You now have filtered collections of 3 totally different object type collections
// and you only ever wrote one single filter.
}
}
So let's say the filter you wrote was like 200 lines of code long... and you had to access three differing parts of the object you are filtering - without a delegate to tell the filter method how to grab the information it needs, you would actually have to write 3 different copies of the same exact filter - or 100 different copies if you had 100 different item types to filter.
but this way you can stick this filter in a DLL somewhere along with a bunch of other usefull stuff and just use it whenever you need it.
anyways - that's just a couple of uses - Once you start using them I garauntee you will find hundreds of uses for them.
></\/~Psightoplasm`~