Учитывая тип C #, получить его базовые классы и реализованные интерфейсы - PullRequest
5 голосов
/ 01 декабря 2009

Я работаю над игровым движком на 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 - Как мне написать ее?

Ответы [ 4 ]

17 голосов
/ 01 декабря 2009

Вы можете написать метод расширения следующим образом:

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());
}
8 голосов
/ 01 декабря 2009

Тип имеет свойство BaseType и метод FindInterfaces.

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

Так что на самом деле у него почти Type.GetAllBaseClassesAndInterfaces, но вы должны сделать два звонка вместо одного.

6 голосов
/ 17 июня 2013

Более точный ответ на основе одного из 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();
}
1 голос
/ 01 декабря 2009

Используйте этот код:

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 примет тип и вернет список своего базового типа плюс интерфейсы.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...