Home > BCL, C#, LINQ, wish > Chain – a LINQ operator for dealing with Linked Lists

Chain – a LINQ operator for dealing with Linked Lists

I don’t think there’s anything in LINQ that will do this, though I expect I’m wrong – I have a tendency to write my own extension method to do something and then discover that LINQ already provides a general version of it. But in the mean time, here’s my Chain method:

public static IEnumerable<T> Chain<T>(this T first, Func<T, T> follow) where T : class
{
    for (T item = first; item != null; item = follow(item))
        yield return item;
}

It’s designed to be used in any situation where a traditional linked list exists. I used it in my AutoDisposal library to get a list of all the types inherited by a given type. It chains a bunch of objects together into an enumerable list by following links between them.

The irritation that provoked this minor burst of creativity is that if you use the GetFields method of Type, there doesn’t seem to be a simple way to get all the instance fields in that type, including inherited ones. By default, GetFields does include inherited fields, but only public ones. To get all public and non-public instance fields, including all inherited ones, you have to walk the chain of base types and get the fields declared in each type. So you’d better use BindingFlags.DeclaredOnly, or you’ll end up with duplicates of the public fields.

I wanted to write a LINQ expression that would get me a single flat list of all the fields in a type, so this is how I used Chain as part of it:

instance.GetType()
    .Chain(type => type.BaseType)
    .SelectMany(type => type.GetFields(BindingFlags.Instance | 
                                       BindingFlags.Public | 
                                       BindingFlags.NonPublic | 
                                       BindingFlags.DeclaredOnly))
    

In this case, the BaseType property of Type is the “next item” pointer in the linked list I’m interested in, but to use LINQ effectively we need it in the form of an IEnumerable<Type>, and so Chain provides a nifty way to do that.

Shouldn’t something like Chain be in the BCL (if it isn’t already?)

Advertisements
Categories: BCL, C#, LINQ, wish Tags: , , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: