views:

232

answers:

3

I'm working on a game engine in C#. The class I'm working on is called CEntityRegistry, and its job is to keep track of the many instances of CEntity in the game. My goal is to be able to query the CEntityRegistry with a given type, and get a list of each CEntity of that type.

What I'd like to do, therefore, is maintain a map:

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

And update the registry thusly:

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

            }
        }

The problem I have is that there is no function Type.GetAllBaseClassesAndInterfaces- How would I go about writing it?

+2  A: 

You could write an extension method like this:

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());
}
SLaks
+1  A: 

Type has a property BaseType and a method FindInterfaces.

http://msdn.microsoft.com/en-us/library/system.type%5Fmembers.aspx

So actually, it almost does have Type.GetAllBaseClassesAndInterfaces, but you have to make two calls instead of one.

Nate C-K
He wants to recurse through the type hierarchy (Hence GetAllBaseClass **es**), so it's not that simple.
SLaks
I guess I'm not sure whether his question was about what method/property to use, or how to write a function that will traverse the inheritance tree. I had assumed the former.
Nate C-K
It might be simpler to make the CEntity constructor register itself with that dictionary instead. Then you don't have to query the inheritance tree for each object. Heavy use of reflection is often an indication that something is wrong with your design.
Nate C-K
A: 

Use this code:

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

The function f will take a Type and return a list of its base type plus interfaces.

Hope it helps.

CesarGon