Consider that you have two objects, Parent and Child. A child has a parent, and a parent maintains an IEnumerable of children.

class Parent
{
    public IEnumerable Children { get; set; } 
}

class Child
{
    public Parent Parent { get; set; } 
}

Given a list of child ids, you need to populate the parent with a list of Child instances, and also set the parent of each child.

Method 1: foreach

First option is to use foreach to iterate through each id in the list, get the child, set the parent on it and add it to the parent’s list of children. Since IEnumerable doesn’t support an Add() method, we need to modify Parent to take a List<> or Collection<> instead, and then we can use the code:

foreach (var id in childIds)
{
    var child = GetChild(id);
    child.Parent = parent;
    parent.Children.Add(child);
}

Now I guess there’s nothing wrong with this; it does get the job done, but when converting a list of something to a list of something else, it seems really wrong not to use linq. Plus, if you were unable to modify the Parent class to use a data type that supported Add(), then this would be out of the questions.

Method 2: linq

parent.Children = childIds.Select(id =>
{
    var child = GetChild(id);
    child.Parent = parent;
    return child;
});

As you can see, although this code has been modified to use linq, the lines match almost one-to-one. We can now, however, leave the Parent’s list of children unchanged, as an IEnumerable. I personally would rather use a single line lambda expression rather than a multiline closure like this though, as I feel they read much better, and make it far clearer to see what the intended action is.

Method 3: object extension

There is a useful linq method, ForEach(), which allows the execution of an action on each item of a list. It returns void, but the behaviour is fairly basic so it is easy enough to knock up a quick extension method to do it. I want to be able to reuse this code, as the ability to update an object within a linq query would be a useful one, so rather than extending Parent you can extend object:

public static object SetProperty(this object entity, Action<object> setter)
{
    setter(entity);
    return entity;
}

This allows for the following code:

parent.Children = childIds
                  .Select(id => GetChild(id).SetProperty(c => (c as Child).Parent = parent))
                  .Select(o => o as Child);

Eeesh. The idea worked in principle, but clearly using an object extension is not the way to go! While I like having the ability to chain the method, it’s not nice to have the nested cast to access the parent property. Furthermore, since the extension method returns object, a further Select was required which simply cast the list items back to Child.

Method 4: generic extension

The final solution is, therefore, fairly obvious, and makes for an elegant and easy-to-read solution.

public static T SetProperty<T>(this T entity, Action<T> setter)
{
    setter(entity);
    return entity;
}
parent.Children = childIds
                  .Select(id => GetChild(id).SetProperty(c => c.Parent = parent));
Share and Enjoy:
  • Print
  • Digg
  • StumbleUpon
  • del.icio.us
  • Facebook
  • Yahoo! Buzz
  • Twitter
  • Google Bookmarks

Leave a reply

required

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>