如何在任意层次结构中找到最具体的类型
How to find the most specific types in an arbitrary hierarchy
假设我们有一组类型:
var types = new[]
{
typeof(IEnumerable<int>),
typeof(ICollection<int>),
typeof(Stack<int>),
typeof(IList<int>),
typeof(int[])
};
如果你考虑类型层次结构,你可以想象:
IEnumerable<int>
|
ICollection<int>
/ \
Stack<int> IList<int>
\
int[]
这不是我的实际问题,但归结为以下问题:
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.
因此,对于上面的集合,叶子将是 Stack<int>
和 int[]
。
如何以优雅的方式做到这一点?任何帮助将不胜感激!
编辑
在我的问题中,我正在处理相互派生的实际类型,创建一棵树。例如,我可以有:
class Root {}
class LeftChild : Root {}
class RightChild : Root {}
class LeftChildChild : LeftChild {}
在这种情况下,我想产生 LeftChildChild
和 RightChild
。
我觉得 Type.IsAssignableFrom
是你的朋友。您想要无法从集合中的任何其他类型分配的类型:
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));
}
}
假设我们有一组类型:
var types = new[]
{
typeof(IEnumerable<int>),
typeof(ICollection<int>),
typeof(Stack<int>),
typeof(IList<int>),
typeof(int[])
};
如果你考虑类型层次结构,你可以想象:
IEnumerable<int>
|
ICollection<int>
/ \
Stack<int> IList<int>
\
int[]
这不是我的实际问题,但归结为以下问题:
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.
因此,对于上面的集合,叶子将是 Stack<int>
和 int[]
。
如何以优雅的方式做到这一点?任何帮助将不胜感激!
编辑
在我的问题中,我正在处理相互派生的实际类型,创建一棵树。例如,我可以有:
class Root {}
class LeftChild : Root {}
class RightChild : Root {}
class LeftChildChild : LeftChild {}
在这种情况下,我想产生 LeftChildChild
和 RightChild
。
我觉得 Type.IsAssignableFrom
是你的朋友。您想要无法从集合中的任何其他类型分配的类型:
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));
}
}