给定C#类型,获取其基类和实现的接口

Mar*_*yer 6 c# reflection inheritance types

我正在研究C#中的游戏引擎.我正在研究的课程被称为CEntityRegistry,它的工作是跟踪CEntity游戏中的许多实例.我的目标是能够CEntityRegistry使用给定的类型查询,并获得每种CEntity类型的列表.

因此,我想做的是维护一张地图:

private IDictionary<Type, HashSet<CEntity>> m_TypeToEntitySet;
Run Code Online (Sandbox Code Playgroud)

并因此更新注册表:

private void m_UpdateEntityList()
        {
            foreach (CEntity theEntity in m_EntitiesToRemove.dequeueAll())
            {
                foreach (HashSet<CEntity> set in m_TypeToEntitySet.Values)
                {
                    if (set.Contains(theEntity))
                        set.Remove(theEntity);
                }
            }
            foreach (CEntity theEntity in m_EntitiesToAdd.dequeueAll())
            {
                Type entityType = theEntity.GetType();
                foreach (Type baseClass in entityType.GetAllBaseClassesAndInterfaces())
                  m_TypeToEntitySet[baseClass].Add(theEntity);

            }
        }
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是没有功能Type.GetAllBaseClassesAndInterfaces- 我将如何写它?

SLa*_*aks 17

您可以编写这样的扩展方法:

public static IEnumerable<Type> GetBaseTypes(this Type type) {
    if(type.BaseType == null) return type.GetInterfaces();

    return Enumerable.Repeat(type.BaseType, 1)
                     .Concat(type.GetInterfaces())
                     .Concat(type.GetInterfaces().SelectMany<Type, Type>(GetBaseTypes))
                     .Concat(type.BaseType.GetBaseTypes());
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*C-K 8

Type具有BaseType属性和FindInterfaces方法.

https://msdn.microsoft.com/en-us/library/system.type.aspx

实际上,它几乎确实有Type.GetAllBaseClassesAndInterfaces,但你必须拨打两个电话而不是一个电话.


dad*_*dhi 6

基于SLaks的更精确答案将是:

public static IEnumerable<Type> GetBaseClassesAndInterfaces(this Type type)
{
    return type.BaseType == typeof(object) 
        ? type.GetInterfaces()
        : Enumerable
            .Repeat(type.BaseType, 1)
            .Concat(type.GetInterfaces())
            .Concat(type.BaseType.GetBaseClassesAndInterfaces())
            .Distinct();
}
Run Code Online (Sandbox Code Playgroud)