Posts
208
Comments
1144
Trackbacks
51
Real world example of C# Anonymous Methods

Often when a new language features come out (in this case anonymous method) we often see syntax examples like this:

delegate void SomeDelegate();
public void InvokeMethod()
{
  SomeDelegate del = delegate()
      {
       MessageBox.Show("Hello");
      };
  del
();  
}

and we say, great but when is code like THAT ever going to be useful to me?  In that trivial example, of course that's not very useful.  But when you consider the power anonymous methods gives you both to pass in parameters and also make use of local objects then tons of possibilities are opened up for making code more concise and efficient.  Consider a case where you're using a DataReader to read multiple result sets.  Your code might look something like this:

public Person GetPerson(int personID)
{
 //(Perform data access code here to create DataReader)
 Person person = new Person();
 
 if (dr.Read())
 {
  person = personMapper.BuildItem(dr);
 }
 
 dr.NextResult();
 if (dr.Read())
 {
  person.Address = addressMapper.BuildItem(dr);
 }
 
 dr.NextResult();
 if (dr.Read())
 {
  person.EmploymentInfo = employmentMapper.BuildItem(dr);
 }
}

This code is now littered with IF statements and dr.NextResult() method calls.  To make this more concise, you could create a simple method that passes in a delegate that you can use anonymously:

public static void ReadNextResult(NullableDataReader dr, Execute execute)
{
 dr.NextResult();
 if (dr.Read())
 {
  execute();
 }
}

Then the consuming code can simply look like this:

public Person GetPerson(int personID)
{
 //(Perform data access code here to create DataReader)
 Person person = new Person();
 
 DataUtil.ReadNextResult(dr, delegate()
  { person = personMapper.BuildItem(dr); });

 DataUtil.ReadNextResult(dr, delegate()
  { person.Address = addressMapper.BuildItem(dr); });

 DataUtil.ReadNextResult(dr, delegate()
  { person.EmploymentInfo = employmentMapper.BuildItem(dr); });  
}

Notice that because of the use of anonymous methods, not only can we pass in the DataReader to the method but also we can use local objects (e.g., the “mapper” objects) inside the anonymous methods.  Internally the C# compiler creates private nested classes containing the delegates we want to execute that have member variables that are assigned the “local object” references which is why it's possible to pull this off in-line rather than having to create a completely separate method.

posted on Tuesday, March 21, 2006 8:51 AM Print
Comments
Gravatar
# re: Real world example of C# Anonymous Methods
Brian
3/24/2006 12:33 PM
It seems you could simplify this even more by creating an enumerable method and including the person object in each call.

e.g.:


using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging;
using System.Data.Common;

namespace TestLib
{

class Person : IEnumerable<Delegate>
{
public string Address;
public string EmploymentInfo;

public Person() { }

public Person GetPerson(int personID)
{
//(Perform data access code here to create DataReader)

Database D = DatabaseFactory.CreateDatabase();
DbCommand cmd = D.GetStoredProcCommand("GetPersonByID");
IDataReader dr = D.ExecuteReader(cmd);

Person person = new Person();

foreach (BuildItem bi in this.GetEnumerator()) { if (dr.Read()) { bi(person, dr); } } //does it all!
}

public delegate void BuildItem(Person p, IDataReader IDR);

public IEnumerator<Delegate> GetEnumerator()
{
yield return new BuildItem(personMapper.BuildItem);
yield return new BuildItem(addressMapper.BuildItem);
yield return new BuildItem(employmentMapper.BuildItem);
}
}

class personMapper
{
public personMapper() { }
public static void BuildItem(Person person, IDataReader IDR) { Person p = new Person(); }
}

class employmentMapper
{
public employmentMapper() {}
public static void BuildItem(Person p, IDataReader IDR) { p.EmploymentInfo = "Employment Info"; }
}

class addressMapper
{
public addressMapper() { }
public static void BuildItem(Person p, IDataReader IDR) { p.Address = "Address Info"; }
}
}



Gravatar
# re: Real world example of C# Anonymous Methods
Steve
3/27/2006 4:54 PM
That is a cool example using iterators. However, I'm not sure I'd consider that more "simplified". :)

Essentially, you still have the 3 lines to call the various mapper BuildItem() methods but they take the form of a yield return with a foreach required. Plus, it necessitates that the various mapper objects are member variables whereas in the original solution you have the flexibility to use mapper objects that have either method level or class level scope (although in your code you changed the BuildItem() methods to be static). But regardless I still think the iterator implementation is a cool example of showing the flexibility that the new language features in C# 2.0 give you!
Gravatar
# re: Real world example of C# Anonymous Methods
Jon Sigler
9/23/2009 8:34 AM
So far...anonymous method appear to be a very poor answer to nested subroutines. I'm not impressed.
Gravatar
# re: Real world example of C# Anonymous Methods
Steve
9/23/2009 8:52 AM
@Jon Sigler - Well, this post was from 3 1/2 years ago so I wouldn't use anonymous methods now that we have the much nicer lambda expression syntax as well as extension methods. Converting the ReadNextResult() method above to be an extension method and taking advantage of lambda, you could now (in C# 3.0) write the above code like this:

dr.ReadNextResult(r => person.Address = addressMapper.BuildItem(r));
dr.ReadNextResult(r => person. EmploymentInfo = employmentMapper.BuildItem(r));

I don't think I follow you regarding "nested subroutines". Without being able to use delegates like this, you'd be lining yourself up to have to write a whole lot of repetitive procedural code. And the syntax is now quite pleasing. I'd being curious to know what alternative you'd prefer.
Gravatar
# re: Real world example of C# Anonymous Methods
Manikanta
3/26/2010 8:37 AM
I want real time examples
Gravatar
# example of C# Anonymous Methods for division
priya
3/13/2014 12:08 AM
2. Create one anonymous method, which takes two inputs from user and divide first input with second and display the result in console. Below are things to be taken care.
a. Take care of divide by zero with proper user intimation
b. Both input and output should be float or double type

Post Comment

Title *
Name *
Email
Comment *  
Verification

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud