首先,开始一些课程:
public abstract class Component
{
GenericSystem mySystem;
public Component() { mySystem = null;}
public void SetSystem(GenericSystem aSystem) { mySystem = aSystem; }
}
public class PhysicsComponent : Component
{
int pos;
public PhysicsComponent(int x) : base() { pos = x; }
}
public abstract class GenericSystem : List<Component>
{
public Type ComponentType;
public GenericSystem(Type componentType)
{ ComponentType = componentType; }
public void RegisterComponent(c)
{
Add(c);
c.SetSystem(this);
}
}
public class PhysicsSystem : GenericSystem
{
public PhysicsSystem() : base(typeof(PhysicsComponent)) { }
}
public static GenericEngine
{
List<GenericSystem> systems = new List<GenericSystem>();
//... Code here that adds some GenericSystems to the systems ...
public static void RegisterComponent(Component c)
{
foreach(GenericSystem aSystem in systems)
{
Type t = aSystem.ComponentType;
//PROBLEM IS HERE
t c_as_t = c as t;
//
if ( c_as_t != null)
aSystem.RegisterComponent(c);
}
}
}
我得到的错误是“无法找到类型或命名空间'。”
我希望每个GenericSystem
都有一个它想要注册的Component
类型。这样,注册新Component c
的任何内容只需调用GenericEngine.RegisterComponent(c)
,所有对该类型组件感兴趣的系统都会注册它。
理想情况下,我希望代码更符合以下几行:
//where T must be a child of Component
public abstract class GenericSystem<T> : List<Component> { /... }
public class PhysicsSystem : GenericSystem<PhysicsComponent>
我怀疑这不是一个非常复杂的问题,而且我错过了一些关于C#如何处理类型(或者更令人尴尬的是一般的泛型)的内容,所以如果这是一个简单的问题,请指出我的方向一些阅读材料。提前谢谢!
答案 0 :(得分:9)
局部变量声明和“as”不起作用。 “t”是在运行时计算为对表示类型的对象的引用的表达式。本地decl和“as”期望一个程序片段在编译时命名一个类型。
你试图把蛋糕放在一堆蛋糕食谱书上;虽然蛋糕和蛋糕食谱书密切相关,但它们并不是一回事。如果要确定在运行时是否对象c是t对象描述的类型,那么可以在c上调用GetType并确定这两种类型是否(1)相等,如果您需要标识,或者(2)兼容,如果你只需要一个兼容另一个。
理想情况下,我希望代码更符合以下几行:
//where T must be a child of Component
public abstract class GenericSystem<T> : List<Component>
好的,然后说:
public abstract class GenericSystem<T> : List<Component> where T : Component
看看你的设计,其他事情似乎很可疑。通用系统实际上是一种组件列表,还是包含组件列表之类的东西?使用推导来表达“是一种”关系。使用包含来表达“容器”关系。汽车不是一种车轮清单;汽车 一个轮子列表。
答案 1 :(得分:1)
首先,你正在写
if ((c as T) != null)
更简单
if (c is T)
然后,正如Eric指出的那样,这些运算符需要类型,而不是包含类型元数据的变量。你需要反思,比如:
if (t.IsAssignableFrom(c.GetType()))