我有一组3个不同的链表(用于保存我正在处理的游戏中的实体).列表是具有相同基本类型的所有对象,但出于处理原因,我将它们分开.请注意,IEntity,IObject和IUndead都继承自IEntity.
public class EntityBucket
{
public LinkedList<IEntity> undeadEntities;
public LinkedList<IEntity> objects;
public LinkedList<IEntity> livingEntities;
public EntityBucket()
{
undeadEntities = new LinkedList<IEntity>();
objects = new LinkedList<IEntity>();
livingEntities = new LinkedList<IEntity>();
}
public LinkedList<IEntity> GetList(IObject e)
{
return objects;
}
public LinkedList<IEntity> GetList(IUndead e)
{
return undeadEntities;
}
public LinkedList<IEntity> GetList(ILiving e)
{
return livingEntities;
}
}
Run Code Online (Sandbox Code Playgroud)
我有3种方法来检索每个列表,目前基于它们的参数.事实上有3个是好的,因为我知道每个列表将以某种方式需要它自己的访问者.传递一个实例化的对象并不理想,因为我可能想要在某个地方检索一个列表而不需要手头有类似类型的对象.请注意,此处的对象甚至不在GetList方法中使用,它们仅用于确定要使用的版本.这是一个我手头有一个实例化对象的例子:
public void Delete(IUndead e, World world)
{
.....
LinkedList<IEntity> list = buckets[k].GetList(e);
.....
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢这个当前的实现,因为我可能并不总是有一个实例化的对象(例如渲染实体时).我一直在考虑这样做,但我不确定这是否可能与我想做的事情有关.有了这个,我还需要3个Delete方法(以及其他3个,例如add等等) - 每种类型一个,IUndead,IObject和ILiving.我觉得这不是正确的做法.
我会根据要求发布我到目前为止尝试做的事情,但我的仿制品相当糟糕,我觉得任何人阅读本文都是浪费.
最后,表现非常重要.我没有过早地进行优化,我已经进行了优化,因为我已经有了工作代码,但需要它更快.getlist方法将经常被调用,我想避免任何显式类型检查.
更好的实现来配合更好的界面怎么样?
public class EntityBucket
{
public LinkedList<IEntity> Entities;
public IEnumerable<T> GetEntities<T>() where T : IEntity
{
return Entities.OfType<T>();
}
}
List<IUndead> myBrainFinders = bucket.GetEntities<IUndead>().ToList();
Run Code Online (Sandbox Code Playgroud)
通过此实现,调用者可以更好地将每个项目添加到正确的列表中。这是您最初实现的要求,所以我认为这没有问题。
public class EntityBucket
{
Dictionary<Type, List<IEntity>> entities = new Dictionary<Type, List<IEntity>>();
public void Add<T>(T item) where T : IEntity
{
Type tType = typeof(T);
if (!entities.ContainsKey(tType))
{
entities.Add(tType, new List<IEntity>());
}
entities[tType].Add(item);
}
public List<T> GetList<T>() where T : IEntity
{
Type tType = typeof(T);
if (!entities.ContainsKey(tType))
{
return new List<T>();
}
return entities[tType].Cast<T>().ToList();
}
public List<IEntity> GetAll()
{
return entities.SelectMany(kvp => kvp.Value)
.Distinct() //to remove items added multiple times, or to multiple lists
.ToList();
}
}
Run Code Online (Sandbox Code Playgroud)