Thursday, March 3, 2011

C# Delegates - How Often Do You Use Them, And When?

Delegates look like such a powerful language feature, but I've yet to find an opportunity to use them in anger (apart from in DALs I must say).

How often do you use them, and under what circumstances do you find them most useful?

From stackoverflow
  • I use them the most for callbacks. Instead of objects for callback methods (using interfaces), I can wrap a method in a delegate and pass that on.

  • I use them for event handlers, callbacks, and predicates to name a few. If you've programmed in C++, you can think of them as function pointers and I think some of their uses become immediately apparent.

    Joel Coehoorn : don't forget lambdas
  • I use C# Delegate the most of time with Event.

    public delegate void MyDelegate(object sender, EventArgs e, string otherParameterIWant);
    //...Inside the class
    public event MyDelegate myEvent;
    //...Inside a method
    if (myEvent != null)
     myEvent(this, new EventArgs(), "Test for SO");
    
  • Events, Predicate Searches, Sometimes inline functionality.. they come in useful in a ton of scenarious..

    List.ForEach(delegate...)

  • Well, with lambda expression added in C#3, they become much easier to use, as the messy parts are hidden.

    myList.Sort(a=> a.LastName);
    
  • I especially like delegates when you have to change out one thing in the middle of boilerplate code:

    public delegate bool ItemFilterDelegate(MyItem item);
    
    public IEnumerable<MyItem> FilterItems(ItemFilterDelegate filter)
    {
        var result = new List<MyItem>();
    
        foreach(MyItem item in AllItems)
        {
            if(filter(item))
                result.Add(item);
        }
    
        return item;
    }    
    
    public IEnumerable<MyItem> FilterByName(string name)
    {
        return FilterItems(item => item.Name == name);
    }
    

    They are ALSO used heavily in this way with LINQ.

    Brian Genisio : As a side note, the ItemFilterDelegate can be completely replaced with Func if you want, but I think calling it out might be a bit more readable.
  • Funcs and Actions are newish "types" of delegates and I use them a lot with Linq and really other odd situations. For Linq they are nice because personally I'd rather have a descriptive name than a lambda expression:

    someList.Select(item => item.Name);
    

    Where with a Func I can:

    Func<Item, String> itemName = item => item.Name;
    ...
    someList.Select(itemName);
    

    It might be a line more, but there are times where I find myself repeating a certain lambda expressions a couple times in a class, so personally I think Funcs work well for that.

    Another situation is a, for lack of a better term, Method Factory. Basically it is a dictionary that holds a list of Actions as the value and say an Enum as the key:

    Dictionary<UserType, Action<User>> showControls;
    showControls = new Dictionary<UserType, Action<User>>();
    
    showControls.Add(SomeEnum.Admin, setControlsForAdmin);
    showControls.Add(SomeEnum.Normal, setControlsForNormalUser);
    showControls.Add(SomeEnum.Unregistered, setControlsForUnregisteredUser);
    

    And then I have the methods themselves written out somewhere else on the page. And use would be:

    showControls[user.UserType]();
    

    Or maybe you want to pass the method itself to another:

    Action<User> neededMethod;
    
    neededMethod = showControls[user.UserType];
    
    SomeMethod(neededMethod);
    

    I'm sure there are much better uses for delegates, but these are useful.

  • I used to use them all the time as Daok says for events, until I learned that you can use built-in handlers for most common events (common for what I do, at least). Now I usually use them as callback handlers for API interaction.

  • I have written this article, maybe that'll help : http://www.codeproject.com/KB/cs/Cs_delegates101_practical.aspx

0 comments:

Post a Comment