How to find the most specific types in an arbitrary hierarchy

Let's say we have a collection of types:

var types = new[]
{
    typeof(IEnumerable<int>),
    typeof(ICollection<int>),
    typeof(Stack<int>),
    typeof(IList<int>),
    typeof(int[])
};

If you think about type hierarchy, you can imagine that:

                     IEnumerable<int>
                           |
                     ICollection<int>
                       /       \
              Stack<int>      IList<int>
                                  \
                                int[]

This isn't my actual problem, but it gets down to the following question:

Given a collection of types that all represent some tree (with a single root), how can I get a subcollection that contains those types that were leaves in the original collection.

So, for the collection above, the leaves would be Stack<int> and int[].

How to do that in an elegant way? Any help will be greatly appreciated!

Edit

In my problem, I am dealing with actual types that derive from each other, creating a tree. For example, I can have:

class Root {}
class LeftChild : Root {}
class RightChild : Root {}
class LeftChildChild : LeftChild {}

In which case I would like to yield LeftChildChild and RightChild.

Jon Skeet
people
quotationmark

It seems to me that Type.IsAssignableFrom is your friend here. You want types that aren't assignable from any of the other types in the set:

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var types = new[]
        {
            typeof(IEnumerable<int>),
            typeof(ICollection<int>),
            typeof(Stack<int>),
            typeof(IList<int>),
            typeof(int[])
        };

        var leaves = types.Where(candidate =>
            !types.Any(t => t != candidate && candidate.IsAssignableFrom(t)));
        Console.WriteLine(string.Join(Environment.NewLine, leaves));
    }
}

people

See more on this question at Stackoverflow