大家好,我在设计游戏的对象存储库时遇到问题:
class ObjectRepository
{
private readonly LevelType _levelType;
private readonly BaseObject[] _darkForestObjects = new BaseObject[]
{ new DarkForestTreeA(), new DarkForestTreeB(), new DarkForestTreeC() };
private readonly BaseObject[] _lightForestObjects = new BaseObject[]
{ new LightForestTreeA(), new LightForestTreeB(), new LightForestTreeC() };
public ObjectRepository(LevelType lt)
{
_levelType = lt;
}
public BaseObject GetObject(int obj)
{
if (obj < 0 || obj > _darkForestObjects.Length)
{
Debug.LogError("Object does not exist.");
return null;
}
switch (_levelType)
{
case LevelType.DarkForest:
return _darkForestObjects[obj];
case LevelType.LightForest:
return _lightForestObjects[obj];
}
return null;
}
}
public enum LevelType
{
DarkForest = 0,
LightForest = 1,
}
我正在寻找一种自动化这个类的方法。通过自动化它我的意思是我不希望每次我创建一个从BaseObject派生的新对象进入Repository类并修改数组。它只是没有看起来很自然。有人能指出我对自动化的建议吗?
答案 0 :(得分:1)
我会对此感到愤怒,所以如果我做错了,请告诉我。
你需要:
现在,我注意到您保存了对象的 dark 和 light 版本的实例。所以我还建议给出一个给定“对象”的明暗版本的持有者类。像这样:
class CompoundObject
{
public BaseObject LightVersion;
public BaseObject DarkVersion;
}
然后您的存储库保留CompoundObject
- 派生对象,而不是在创建时添加自己的BaseObject
个对象,CompoundObject
对象就可以执行此操作。
现在关于数组操作,你可能是对的;它有点笨重。我建议采用List<CompoundObject>
代替CompoundObject[]
。通用List提供非常方便的方法,如添加和删除,可以简化您的集合操作。
答案 1 :(得分:1)
如果我是你,我会选择使用接口的更通用的解决方案。 考虑到您的示例,我假设您有多个级别类型,它们具有自己特定的TreeA,TreeB和TreeC实现。 如果我理解正确,我宁愿为每种树类型使用接口。 TreeA的示例:
public interface ITreeA
{
// any common public members here
}
public class DarkForestTreeA : ITreeA, BaseObject
{
...
}
public class LightForestTreeA : ITreeA, BaseObject
{
...
}
这样,您可以要求您的存储库提供特定于级别类型的ITreeA实现。类似的东西:
public T GetObject<T>() // where T could be ITreeA, ITreeB...
{
...
}
因此,如果级别类型为DarkForest,则可以调用myRepo.GetObject()并获取DarkForestTreeA对象。
要实现此行为&#34;自动化&#34;,您可以在唯一的命名空间中声明DarkForest的所有特定实现,然后使用反射来查找实现ITreeA的命名空间的类。这在性能方面可能效率不高,但它为您提供了极大的灵活性,因为您只需在命名空间中添加新类即可从存储库中获取它们。但是,它也可能带来其他问题(例如,如果在同一名称空间中有两个实现ITreeA的类会发生什么?)。 有关实施详情,请参阅Getting all types in a namespace via reflection和Getting all types that implement an interface with C# 3.0。
我必须承认这不是最简单的解决方案。
您可以考虑更简单的事情,例如为对象类型定义字典(treeA,treeB),然后为每种级别类型定义字典,将对象类型映射到其具体实现。 例如:
public enum ObjectType
{
TreeA,
TreeB,
TreeC,
}
Dictionary<ObjectType, Type> DarkForestObjectTypes = new Dictionary<ObjectType, Type>()
{
{ ObjectType.TreeA, typeof(DarkForestTreeA) },
{ ObjectType.TreeB, typeof(DarkForestTreeB) }
...
}
由于这个答案看起来有些混乱,我不会详细了解更多细节,但希望它会给你提供继续的想法。