简体   繁体   中英

Anonymous Delegates and generic Lists in C#

Can you explain me code below :

private static List<Post> _Posts;
public static Post GetPost(Guid id)
{
    return _Posts.Find(delegate(Post p)
    {
        return p.Id == id;
    });
}
  1. What is the point to find an object in a generic list by that way ? He can simply iterate the list.

  2. How this delegated method called for each element of list ?

NOTE : if this has a common name, can you update my question's title ?

Thanks !

You're quite right he can iterate over the list, you can think of the code in your question as being conceptually the same as the following:

private static Post GetPost(Guid id)
{
    Post p = default(Post);

    foreach (Post post in _Posts)
    {
        if (post.Id == id)
        {
            p = post;
            break;
        }
    }

    return p;
}

It requires less code to write your snippet and importantly you are now saying what you want to be found and not exactly how to find it:

private static Post GetPost(Guid id)
{
    return _Posts.Find(delegate(Post p)
    {
        return p.Id == id;
    });
}

In C# 3.0 this can be shortened further using what is called a " lambda expression " to:

private static Post NewGetPost(Guid id)
{
    return _Posts.Find(p => p.Id == id);
}

Using the least amount of readable code to achieve the same goal makes both writers and readers of that code happier.

He is using an anonymous delegate. He could have used a lambda expression instead:

Posts.Find(p => p.Id == id)

Also, wrapping access to the list in a method achieves nothing in this case and exposes the elements of the list to external callers. This is bad practice.

  1. List basically goes through each element and checks whether the element returns true for that Predicate<T> . It is essentially a shortcut so that you don't have to iterate over the list. List<T>.Find(Predicate<T>) might also have some built-in optimizations.
  2. You call a delegate using the syntax:

delegateInstance(arg1,arg2);

If you are using C# 3.0 or later you can use Linq to find objects quickly in a List.

public static Post GetPost(Guid id)
{
    return (from p in _Posts
            where p.Id == id
            select p).First();
}

List.Find(Predicate match) is NOT a LINQ extension method, because this method has been in the framework since 2.0, as is indicated by MSDN. Second, there is nothing wrong with using Find(). It tends to be more readable than its alternatives:

Classic:

public static Post GetPost(Guid id)
{
  bool found = false;

  foreach(post in _Posts)
  { 
    if post.Id == id return post;
  }
  return default(Post);
}

LINQ:

public static Post GetPost(Guid id)
{
  var post = (
    from p in _Posts 
    where p.Id = id 
    select p
  ).FirstOrDefault();
}

Using List.Find() tells you immediately that you are look for an item, while the other you have to follow logic to ascertain this. Find() basically encapsulates the iteration over the list items. If you had a method on the Post class like public bool HasId(Guid id) then you could write

_Post.Find(post.HasId(id));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM