我知道如何使用 typeof(T).GetInterfaces()
获取 T 的所有接口(interface),但我需要确切的继承树。
是否可以通过现有的反射 API 以某种方式解决这个问题?
编辑: 请允许我澄清一下:
interface Base1 {}
interface Base2 {}
interface Foo : Base1
interface Final : Foo, Base2
我想形成一棵代表Final层次结构的树。
我已经对 NGenerics 有依赖性,所以使用它来实现树不是问题。
最佳答案
让我们看看。据我所知,没有 BCL 方法可以仅获取在特定类型上实际实现的接口(interface),但排除任何类型继承的接口(interface)。所以我们必须自己动手:
public static Dictionary<Type, IEnumerable<Type>> GetInterfaceHierarchyMap(this Type type)
{
List<Type> typeAncestry = new List<Type>();
Type ancestor = type;
while(ancestor != null)
{
typeAncestry.Add(ancestor);
ancestor = ancestor.BaseType;
}
Dictionary<Type, IEnumerable<Type>> interfaceMaps = new Dictionary<Type, IEnumerable<Type>>();
foreach(Type childType in typeAncestry.Reverse<Type>())
{
var mappedInterfaces = interfaceMaps.SelectMany(kvp => kvp.Value);
var allInterfacesToPoint = childType.GetInterfaces();
interfaceMaps.Add(childType, allInterfacesToPoint.Except(mappedInterfaces));
}
return interfaceMaps;
}
一步一步:
- 我们从当前类型开始,向上走 BaseType直到我们到达根类型。
- 我们反转列表,因此当我们迭代它时,我们首先从根类型开始。
- 对于链下的每个类型,我们获取应用于该类型并从祖先类型继承的所有接口(interface),然后我们使用 Except以消除我们在之前的迭代中已经找到的所有那些。
这会将重复的接口(interface)要求视为多余 - 即,如果您的祖先类型之一实现了 IDisposable 而您的类型也实现了,则只会计算最早的实现。
这个方法的假设结果是一个看起来像这样的字典:
[object] - []
[BaseBaseClass] - [ISomeInterface]
[BaseClass] - [IAnotherInterface, IOneMore]
[ConcreteClass] - [IYetAnother]
关于c# - 如何形成一棵代表接口(interface)继承树的树?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4102716/