.NET Tip of The Day
Learn one new .NET trick every day
Быстрое пополнение счета телефона      Login or Join

Create elegant code with Action delegate and List.ForEach method

Let's review the following code which works with generic collection:

    List<Tip> tips = new List<Tip>();        //represents a list of Tips

    ...

 

    //create SiteMapNode from each Tip

    foreach (Tip tip in tips)

    {

        string url = string.Format("{0}/tips/{1}.aspx", appPath, tip.Id);

        SiteMapNode node = new SiteMapNode(this, url, url, tip.Title);

        node["lastmod"] = tip.PubDate.ToString("u");

        AddNode(node, rootNode);

    }

Although this code works well we can improve it using Action delegate and List.ForEach method. First we have to exctract code to create SiteMapNode into a method:

    private void AddSiteMapNode(Tip tip)

    {

        string url = string.Format("{0}/tips/{1}.aspx", appPath, tip.Id);

        SiteMapNode node = new SiteMapNode(this, url, url, tip.Title);

        node["lastmod"] = tip.PubDate.ToString("u");

        AddNode(node, rootNode);

    }

Separating it into a separate method has a few advantages, practically the ability to reuse the same logic for other uses. Now once we have this method creating SiteMapNode's from Tips collection would be:

    tips.ForEach(AddSiteMapNode);

P.S. this tip also can be used with Array.ForEach method.

11/11/2007

Comments:

Much more elegant with anonymous delegate

Diego Guidi 11/12/2007 4:40:37 PM

And even more elegant with lambda expressions.

listInstance.ForEach(new Action(a=> {
string url = string.Format("{0}/tips/{1}.aspx", appPath, tip.Id);

SiteMapNode node = new SiteMapNode(this, url, url, tip.Title);

node["lastmod"] = tip.PubDate.ToString("u");

AddNode(node, rootNode);
}));

Vijay Santhanam 11/12/2007 4:45:03 PM

First, cool tip! I will definitely use this.

Diego & Vijay, I believe the whole point of this article is that this allows you to reuse the method, and have it NOT be a cryptic anonymous method.

The Action delegate is something I don't think many people have seen before (I know I hadn't).

Mike Duncan 11/12/2007 9:50:15 PM

I would do null checking first before doing the ForEach

tips.FindAll(delegate(Tip p1){return p1 != null;}).
ForEach(AddSiteMapNode);

Dennis Olano 11/14/2007 2:02:13 AM

Mike you got the point right. Anonymous delegate/lambda expressions are good if you don't have plans to reuse it's code. Regular method is good if you have plans to reuse it. So I think both options are valid but in different cases.

kostya.ly 11/14/2007 4:59:37 PM

You can easily extend this function to work on all IEnumerable classes with an extension method.

public static class Extensions
{

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
}
}
}

Cameron MacFarland 1/15/2008 8:22:59 AM

i compared ForEach extension method performance with classic foreach. i did not know that there is such performance difference. i'm really interested using ForEach because of nice flexibility and style, but i found i'll achieve better performance by using it.

Reza Owliaei 2/21/2009 11:15:07 AM

Name
URL
E-mail
Provide your e-mail address to receive notification about new comments.
Message
HTML tags are not supported.
Please add 7 and 4 and type the answer here:
RSS .NET Tip of The Day
Subscribe to receive one tip from the .NET Tips and Tricks Community per day.
Previous Tips of The Day
The best of the .NET Tips & Tricks Community.
.NET Practitioners .NET Tips & Tricks Community
Every .NET practitioner has a trick up in their sleeve. This is the place to share it with other .NET people.
Submit a Tip
Discovered a new trick? Share it with others.
My Tips
Manage tips you authored.