tags:

views:

4774

answers:

22

What are your usage of delegates in C#?

+3  A: 

subscribing eventhandlers to events

Manu
+45  A: 

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)
Jon Skeet
Worth mentioning the "push" in Push LINQ?
Marc Gravell
Not sure how I'd explain it briefly without making things more confusing :)(Arguably it's covered by event handlers, LINQ, and the templaty bit anyway!
Jon Skeet
Your first sentence doesn't make much sense.
senfo
@senfo: Does it make more sense now?
Jon Skeet
I know what you're trying to say, but I would find the following easier to read: "Now that we have lambda expressions and anonymous methods in C#, I use delegates much more." I know I'm nitpicking, but I really had to read that sentence a few times before it made sense to me.
senfo
But for what it's worth, I like your answer and voted you up. ;-)
senfo
A: 
  1. For event handler

  2. To pass method in a method parameters

Daok
A: 

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.

x0n
A: 

Events, other anynch operations

A: 

I've used it for Invoking GUI stuff from separate threads.

Here's a link to an example.

itsmatt
The MSDN example is vastly overcomplicated, though; much simpler to just do this.Invoke((MethodInvoker)delegate { /* some code */ });
Marc Gravell
Perhaps, but there is some discussion about the issue there, which is why I linked to it.
itsmatt
A: 

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.

Bob King
A: 

events gfdsg

A: 

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.

Santiago Palladino
Minor point, but re "more precisely, lambdas" - you could do the same with an anonymous method in C# 2.0, although it would be more verbose: delegate (ItemType item) { [return] Download(item);}
Marc Gravell
Sure, same as LINQ: lambdas are nothing more than syntactic sugar for delegates. They just made delegates more accessible.
Santiago Palladino
Lambdas are slightly more than just delegates, as they're convertible to expression trees as well as delegates.
Jon Skeet
Well, lambdas can also be compiled to Expressions, which are *completely* different from delegates. But your example used Func<,>, which can be used from an anon-method. Expressions would be extremely painful to write in C# 2.0.
Marc Gravell
+4  A: 

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.

Marc Gravell
+5  A: 

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] );
    } );
harpo
A: 

Usage of delegates

  1. Event Handling
  2. Multi Casting
Rajeshwaran S P
A: 

The comparison param in In Array.Sort(T[] array, Comparison comparison), List.Sort(Comparison comparison), etc

GregUzelac
+2  A: 

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.

Maxim
A: 

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.

deadcat
+6  A: 

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");
    }
}
Andrew Hare
+3  A: 

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.

Reed Copsey
+5  A: 

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!

jonnii
A: 

This question seems to be a dupe of this one.

However, there's a good tutorial on MSDN that you should read.

Dan Diplo
A: 
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 ;)

joe
That's not valid c# code.
qstarin
@qstarin I think your missing the point.
joe
@joe: you're right, I don't at all see the point of an answer to a 2 year old question that appears to provide no information whatsoever and uses a code snippet that wouldn't even compile.
qstarin
@qstarin is correct. This is not valid code. `man.Feed = getBreakfast;` would be more appropriate, assuming Feed is a property of a delegate type and `getBreakfast` (btw, stylecop would not be happy with that method name) were a method in the current type that matches the delegate signature.
Will
A: 

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.

DeadMG