简体   繁体   English

如何在任意层次结构中查找最具体的类型

[英]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[] . 因此,对于上面的集合,叶子将是Stack<int>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 . 在这种情况下,我想产生LeftChildChildRightChild

It seems to me that Type.IsAssignableFrom is your friend here. 在我看来, Type.IsAssignableFrom是您的朋友。 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));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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