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

时间:2009-12-01 02:34:13

标签: c# reflection inheritance types

我正在使用C#中的游戏引擎。我正在处理的课程称为CEntityRegistry,其工作是跟踪游戏中CEntity的许多实例。我的目标是能够使用给定类型查询CEntityRegistry,并获取该类型的每个CEntity的列表。

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

private IDictionary<Type, HashSet<CEntity>> m_TypeToEntitySet;

然后更新注册表:

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);

            }
        }

我遇到的问题是没有函数Type.GetAllBaseClassesAndInterfaces - 我将如何编写它?

5 个答案:

答案 0 :(得分: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());
}

答案 1 :(得分:8)

Type有一个属性BaseType和一个FindInterfaces方法。

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

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

答案 2 :(得分: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();
}

答案 3 :(得分:1)

使用此代码:

Func<Type, List<Type>> f = ty =>
{
    var tysReturn = new List<Type>();
    if (ty.BaseType != null)
    {
        tysReturn.Add(ty.BaseType);
    }
    tysReturn.AddRange(ty.GetInterfaces());
    return tysReturn;
};

函数f将接受一个Type并返回其基类型和接口的列表。

希望它有所帮助。

答案 4 :(得分:1)

这里。先前的答案有问题。 另外,此答案不需要“不同”。这些值已经不同。而且这个效率更高。

    public static IEnumerable<Type> GetBaseTypes(this Type type, bool bIncludeInterfaces = false)
    {
        if (type == null)
            yield break;

        for (var nextType = type.BaseType; nextType != null; nextType = nextType.BaseType)
            yield return nextType;

        if (!bIncludeInterfaces)
            yield break;

        foreach (var i in type.GetInterfaces())
            yield return i;
    }