What are your usage of delegates in C#?
Now that we have lambda expressions and anonymous methods in C#, I use delegates much more. In C# 1, where you always had to have a separate method to implement the logic, using a delegate often didn't make sense. These days I use delegates for:
- Event handlers (for GUI and more)
- Starting threads
- Callbacks (e.g. for async APIs)
- LINQ and similar (List.Find etc)
- Anywhere else where I want to effectively apply "template" code with some specialized logic inside (where the delegate provides the specialization)
The first line of usage is to replace the Observer/Observable (events) pattern. The second, a nice elegant version of the Strategy pattern. Various other usages can be gathered, though more esoteric than these first two I think.
I've used it for Invoking GUI stuff from separate threads.
Here's a link to an example.
Any time you want to encapsulate behavior, but invoke it in a uniform way. Event Handlers, call-back functions, etc. You can accomplish similar things using Interfaces and casts, but sometimes, behavior isn't necessarily tied to a type or object. Sometimes you just have behavior you need to encapsulate.
Lazy parameter initialization! Besides all previous answers (strategy pattern, observer pattern, etc), delegates allow you to handle lazy initialization of parameters. For example, suppose you have a function Download() which takes quite a lot of time and returns a certain DownloadedObject. This object is consumed by a Storage depending on a certain Conditions. Typically, you would:
storage.Store(conditions, Download(item))
However, with delegates (more precisely, lambdas) you can do the following, by changing the signature of store so that it receives a Condition and a Func<Item,DownloadedObject> and use it like this:
storage.Store(conditions, (item) => Download(item))
Therefore, storage will only evaluate the delegate if necessary, executing download depending on Conditions.
A slightly different use is to speed up reflection; i.e. instead of using reflection each time, you can use Delegate.CreateDelegate
to create a (typed) delegate to a method (a MethodInfo
), and call that delegate instead. This is then much quicker per call, as the checks have already been done.
With Expression
, you can also do the same to create code on the fly - for example, you can easily create an Expression
that represents the + operator for a type chosen at runtime (to provide operator support for generics, which the language doesn't provide); and you can compile an Expression
to a typed delegate - job done.
You can use delegates to declare function-typed variables and parameters.
Example
Consider the "resource borrowing" pattern. You want to control the creation and cleanup of a resource, while allowing client code to "borrow" the resource in between.
This declares a delegate type.
public delegate void DataReaderUser( System.Data.IDataReader dataReader );
Any method matching this signature can be used to instantiate a delegate of this type. In C# 2.0, this can be done implicitly, simply by using method's name, as well as by using anonymous methods.
This method uses the type as a parameter. Note the delegate's invocation.
public class DataProvider
{
protected string _connectionString;
public DataProvider( string psConnectionString )
{
_connectionString = psConnectionString;
}
public void UseReader( string psSELECT, DataReaderUser readerUser )
{
using ( SqlConnection connection = new SqlConnection( _connectionString ) )
try
{
SqlCommand command = new SqlCommand( psSELECT, connection );
connection.Open();
SqlDataReader reader = command.ExecuteReader();
while ( reader.Read() )
readerUser( reader ); // the delegate is invoked
}
catch ( System.Exception ex )
{
// handle exception
throw ex;
}
}
}
The function can be called with an anonymous method as follows. Note that the anonymous method can use variables declared outside of itself. This is extremely handy (although the example is a little contrived).
string sTableName = "test";
string sQuery = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" + sTableName + "'";
DataProvider.UseReader( sQuery,
delegate( System.Data.IDataReader reader )
{
Console.WriteLine( sTableName + "." + reader[0] );
} );
The comparison param in In Array.Sort(T[] array, Comparison comparison), List.Sort(Comparison comparison), etc
Found another interesting answer:
A coworker just asked me this question - what's the point of delegates in .NET? My answer was very short and one that he had not found online: to delay execution of a method.
Source: LosTechies
Just like LINQ is doing.
I use delegates to communicate with threads.
For example, I might have a win forms app which downloads a file. The app starts a worker thread to do the download (which prevents the GUI from locking up). The worker thread uses delegates to send status messages (eg download progress) back to the main program, so that the GUI can update the status bar.
Delegates are very useful for many purposes.
One such purpose is to use them for filtering sequences of data. In this instance you would use a predicate delegate which accepts one argument and returns true or false depending on the implementation of the delegate itself.
Here is a silly example - I am sure you can extrapolate something more useful out of this:
using System;
using System.Linq;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<String> names = new List<String>
{
"Nicole Hare",
"Michael Hare",
"Joe Hare",
"Sammy Hare",
"George Washington",
};
// Here I am passing "inMyFamily" to the "Where" extension method
// on my List<String>. The C# compiler automatically creates
// a delegate instance for me.
IEnumerable<String> myFamily = names.Where(inMyFamily);
foreach (String name in myFamily)
Console.WriteLine(name);
}
static Boolean inMyFamily(String name)
{
return name.EndsWith("Hare");
}
}
Delegates are used any time you use events - that's the mechanism by which they work.
In addition, delegates are very useful for things such as using LINQ queries. For example, many LINQ queries take a delegate (often Func<T,TResult>
) which can be used for filtering.
Delegates can often be used in place of an interface with one method, a common example of this would be the observer pattern. In other languages if you want to receive a notification that something has happened you might define something like:
class IObserver{ void Notify(...); }
In C# this is more commonly expressed using events, where the handler is a delegate, for example:
myObject.SomeEvent += delegate{ Console.WriteLine("..."); };
Another great place to use delegates if when you have to pass a predicate into a function, for example when selecting a set of items from a list:
myList.Where(i => i > 10);
The above is an example of the lambda syntax, which could also have been written as follows:
myList.Where(delegate(int i){ return i > 10; });
Another place where it can be useful to use delegates is to register factory functions, for example:
myFactory.RegisterFactory(Widgets.Foo, () => new FooWidget());
var widget = myFactory.BuildWidget(Widgets.Foo);
I hope this helps!
This question seems to be a dupe of this one.
However, there's a good tutorial on MSDN that you should read.
Man man = getMan();
if (time == "morning"){
man.feed = getBreakfast(); //feed is a delegate
} else {
man.feed = getLunch();
}
Now later in your code when you call man.feed() you know he will get the right meal ;)
As far as I know, delegates can be converted to function pointers. This makes life MUCH easier when interoperating with native code that takes function pointers, as they can effectively be object-orientated, even though the original programmer didn't make any provision for that to happen.