The Power of Anonymous Methods in C#

Anonymous methods are a new feature in C# 2.0 that allow you to hook an action directly to an event as opposed to having a separate event handler.  For example, when a user clicks a button and you need to pop-up a MessageBox, you could handle it the standard way with a delegate and an event handler, or you could hook the action to perform directly to the Click event using an anonymous method as shown next:

btnSubmit.Click += delegate(object sender,EventArgs e)
{
    MessageBox.Show(
"Thanks for clicking the button!");
});

Looking through the code you'll see that no method name is given to the inline event handler method.  Instead it uses the delegate keyword and defines the parameters that the event handler would normally expect. 

I've not a big fan of using anonymous methods for things like button clicks, DropDownList SelectedIndexChanged events, etc. although they're certainly valid in those scenarios.  Where I do think anonymous methods are quite useful is in situations where a collection needs to be quickly sorted and I don't feel like implementing the IComparable<T> interface on the class (or creating a custom sort class with IComparer<T>).  There are many other examples of where they could be used as well such as with Array.ForEach()<T>, etc.  Basically, anytime you see a method that accepts a delegate as a parameter you could use anonymous methods.

To see how anonymous methods can be used for sorting, assume that you have the following Customer class defined and you'd like to easily sort a list of Customer objects based on Name, Age or CustomerSince (date):

public class Customer
{
    
private DateTime _CustomerSince;
    private int 
_Age;
    private string 
_Name;

    public 
DateTime CustomerSince
    {
        
get return _CustomerSince}
        
set { _CustomerSince = value; }
    }

    
public int Age
    {
        
get return _Age}
        
set { _Age = value; }
    }

    
public string Name
    {
        
get return _Name}
        
set { _Name = value; }
    }
}

You can sort a List<Customer> based upon different criteria by using anonymous methods and the Comparer<T> class.  Here's an example of performing different types of sorts using anonymous methods and the List<T> Sort() method.  By using this technique you write a minimal amount of code and keep it concise since the delegate and handler are defined together.

static void Main(string[] args)
{
    List<Customer> custs 
= new List<Customer>();
    
Customer cust1 = new Customer();
    
cust1.Age 35;
    
cust1.Name "John Doe";
    
cust1.CustomerSince = new DateTime(200011);

    
Customer cust2 = new Customer();
    
cust2.Age 33;
    
cust2.Name "Jamie Doe";
    
cust2.CustomerSince = new DateTime(200641);

    
Customer cust3 = new Customer();
    
cust3.Age 10;
    
cust3.Name "Jane Doe";
    
cust3.CustomerSince = new DateTime(199921);

    
custs.Add(cust1);
    
custs.Add(cust2);
    
custs.Add(cust3);

    
Console.WriteLine("Sorting by CustomerSince date:");
    
custs.Sort(delegate(Customer c1, Customer c2)
    {
        
return Comparer<DateTime>.Default.Compare(c1.CustomerSince, 
            c2.CustomerSince)
;
    
});

    foreach 
(Customer cust in custs)
    {
        Console.WriteLine(cust.Name + 
" " 
            cust.CustomerSince.ToShortDateString())
;
    
}

    Console.WriteLine(
"\r\nSorting by Age:");
    
custs.Sort(delegate(Customer c1, Customer c2)
    {
        
return Comparer<int>.Default.Compare(c1.Age, c2.Age);
    
});

    foreach 
(Customer cust in custs)
    {
        Console.WriteLine(cust.Name + 
" " + cust.Age.ToString());
    
}
    Console.Read()
;
}

In addition to using anonymous methods, this code relies upon the Comparer<T> generic class to specify the type that should be sorted as well as the objects to compare.  Although I used standard foreach loops above, anonymous methods could've been used to accomplish looping as well if I really wanted to go wild with them.

If you find yourself doing this type of sorting a lot you may want to explore creating a custom class that implements the IComparable<T> interface. However, in cases where you just need to perform a sort quickly and easily, anonymous methods are very useful.  The code shown in this example can be download here.

Published Monday, April 23, 2007 10:57 AM by dwahlin
Filed under: ,

Comments

# re: The Power of Anonymous Methods in C#

Tuesday, April 24, 2007 1:03 PM by Dejan Cusic

Hi,

just to be consistent, following code:

foreach (Customer cust in custs)

   {

       Console.WriteLine(cust.Name + " " + cust.Age.ToString());

   }

Could be (with anonymus method):

custs.ForEach(delegate (Customer cust)

{

       Console.WriteLine(cust.Name + " " + cust.Age.ToString());

})

just to show leverage of the anonymus methods.

# re: The Power of Anonymous Methods in C#

Tuesday, April 24, 2007 1:42 PM by Sergio Pereira

Some of my favorite .Net 2.0 methods are in List<T> ... Check the FindXXXXXX(Predicate<T>) and ConvertAll<TOut>() methods. There are static equivalents in the Array class, like FindXXXX<T>( ... ).

Sweet.

# re: The Power of Anonymous Methods in C#

Tuesday, April 24, 2007 2:07 PM by dwahlin

Thanks Dejan.  That was the "I could go wild" part I mentioned at the end of the post.  I'm going to go ahead and leave the code "as is" since your comment sums up how to do that perfectly.

# re: The Power of Anonymous Methods in C#

Wednesday, April 25, 2007 2:13 PM by Derik Whittaker

Dan,

I love anonymous methods, but the one thing i hate about them is that they are hard to test (via unit tests).  In your sort example.  How do you test that?  I understand this is just an example, but to me if it hard to test then it is not worth doing/using.

Derik

# re: The Power of Anonymous Methods in C#

Saturday, April 28, 2007 11:11 AM by Mohammad Nour

I love this article. Simple and Direct.