List.Find() and Predicates in C#

I’ve been finding all kinds of cool stuff in .net 2.0 that I didn’t know about. Today I discovered predicates.

I’m not sure how to explain it so I’ll just give an example. I have a List of Tasks and I want to return the task with the selected id. Normally I would write a loop like the one below:

int id = int.Parse(taskList.SelectedValue);
foreach (Task t in AllTasks)
{
	if (t.Id == id)
		return t;
}

It’s a common enough operation and I have written several loops just like it. I never really enjoy writing the above code. I would probably create a TaskCollection class and move the above loop into it eventually.

Now with .net 2.0 I can write the same thing in two lines:

int id = int.Parse(taskList.SelectedValue);
return AllTasks.Find(delegate(Task t) { return t.Id == id; });

And at first glance I like this a lot better. I’m a little concerned that this functionality could be abused to write some very ugly code. I still think it should be moved to my TaskCollection class at some point, but I’m less likely to do so now because it is only one line.

Posted in Software Development and tagged . Permalink.

22 Responses to List.Find() and Predicates in C#

  1. Excelent article, nice and easy

  2. Excellent. Explained in 2 lines what Visual Studio help couldn’t in 100.

    David
  3. defi. a gr8 explanation..

    kk
  4. True, but one could argue about the readability of the code. There’s no performance enhancement to consider, so here goes: What’s easier to comprehend?

    foreach (Task t in AllTasks){ if (t.Id == id) return t; }
    or
    return AllTasks.Find(delegate(Task t) { return t.Id == id; });

  5. Seems pretty familiar. I used to do this in javascript passing a function to a function. Is it the same thingie? Great finding! Thanks.

    Kazi Rameez
  6. Yeah, it’s pretty much the same idea as passing a function in JavaScript.

    (There are a few differences due to C# type strictness and JavaScript treating functions as objects, but the concept is the same.)

  7. //—————————————————————————————————————-
    // I finaly discovered that this is not faster then iterating through each object in the collection with a ForEach
    //—————————————————————————————————————-
    object[] ItemFound = Items.Find(delegate(object[] Item) { return Item.GetValue(0).ToString() == lstItems.SelectedItem.ToString(); });

    Marc
  8. No, it is not really any faster than looping through and returning the first match youself. It can’t be if you think about it. However, it is a little more succinct and states more explicitly what you want to achieve.

    object[] itemFound = items.Find(delegate(object[] item) { return item[0].ToString() == listItems.SelectedItem.ToString(); });

    vs.

    object[] itemFound;
    foreach (object[] item in items)
    {
        if (item[0].ToString() == listItems.SelectedItem.ToString)
        {
            itemFound = item;
            break;
        }
    }
    and you can make it even shorter in C# 3.0 / .net 3.5 / Visual Studio 2008:

    object[] itemFound = items.Find(item => item[0].ToString() == listItems.SelectedItem.ToString());

    (I’m not positive that is the correct syntax since I haven’t used it much yet. Also, you might be able to get rid of the ToString. I don’t know the app, so maybe it is needed.

  9. And what if i have for example List = (0,1,2,3) and i am looking for integer greater than 4, and this method (if failed) returns me 0… but 0 is not what i would like to get, 0 isn’t greater than 4…

    Thanks for any nice and elegant solution!

    majk
  10. What if I want to check if (t == null) before I access the property t.Id ?

    If I try to fit that all in one line it’s not readable any more.

    Any thoughts ?

  11. Has anyone taken this to the next level, and worked it with Generics?

  12. Excellent example. Thanks!

    Jeff
  13. Hey nice article, i wasn’t knowing that,it was really helpful

    Aditya Kanekar
  14. Pingback: List.Find() and Predicates in C# « using …

  15. Clear and precise!

    Jovica
  16. Thank you so much for this simple and concise example! If only MSDN could provide documentation that was actually meant to be useful to humans.

    Matt
  17. Thanx a LOT! Made my life a lot easier ;-)

  18. Thankyou for that 1 line of code I needed. Writers for MSDN and others must be paid by the word because they take forever to get to the point.

    Craig
  19. same idea could be implemented with Lambdas Expression
    instead:
    return AllTasks.Find(delegate(Task t) { return t.Id == id; });

    use:
    return AllTasks.Find(e==> e.Id == id);
    See: http://mgznet.com/WorkingWithListObject.aspx

    GZ
  20. This could be done very easily using lamda expressions and the code is very readable too..

    return AllTasks.Find(t=>t.Id == int.Parse(taskList.SelectedValue.ToString()));

    Balaji Birajdar
  21. Very helpful example! Showing the before / after is great. This has saved me a lot of time. I’m using this to move one item in a list to the top of the list.

    Ron
  22. And what is about the performance of Lambdas Expression? Is it faster then “foreach” example in above?

    www.eoling.com hotels

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>