你好denizens堆栈溢出,我有一个问题(也许与理解?)关于多态性和泛型。我希望能够定义一个包含“组件”的“系统”。我也希望能够扩展系统和组件,以便能够拥有更强大的功能。C#泛型与多态性
我目前有两个基类,组件,以及I/A_ComponentSystem(为简便起见,我不会被显示任何实际的代码,只需定义):
public abstract class Component { }
public interface IComponentSystem { }
public interface IComponentSystem<TComponent> : IComponentSystem
where TComponent : Component { }
// The following are what should should actually be inherited from
public abstract class AComponentSystem : IComponentSystem { }
public abstract class AComponentSystem<TComponent> : AComponentSystem
where TComponent : Component { }
下面是一个例如组件/系统创建:
public abstract class ITag : Component { } // This is to allow generating the code in a different binary. Hard to explain in the question, I'll clarify if need be
public class Tag : ITag { }
public abstract class ITagSystem : AComponentSystem<ITag> { }
public class TagSystem : ITagSystem { }
下面是实际上是试图使用代码/不同对象之间的变形(请注意,该代码并不意味着以这种方式使用的一些摘录,但我m写单元测试以确保层之间的兼容性)
// This is the main system that will be passed around
TagSystem tagSys = new TagSystem();
// This is OK
ITagSystem ITagSys = (ITagSystem)ITagSys;
// This is OK
AComponentSystem A_TagSys = (AComponentSystem)tagSys;
// This is OK
AComponentSystem<ITag> ATag_TagSys = (AComponentSystem<ITag>)tagSys;
// This is OK
IComponentSystem I_TagSys = (IComponentSystem)tagSys;
// This is OK
IComponentSystem<ITag> ITag_TagSys = (IComponentSystem<ITag>)tagSys;
// Even the following is OK (which is why I am confused)
IComponentSystem<Tag> new_ITag_TagSys = (IComponentSystem<Tag>)tagSys;
//***This is where it blows up*** (1)
AComponentSystem<Tag> new_ATag_TagSys = (AComponentSystem<Tag>)tagSys;
我有另一个接口/类,的SystemManager,它正是如此定义:
public interface ISystemManager
{
TComponent AddNewComponentToEntity<TComponent, TComponentSystem>(Entity e) // Please don't ask about Entity, it shouldn't be required for this snippet and I already feel like I've posted a lot)
where TComponent : Component, new() // Required for some reason or I get an error
where TComponentSystem : IComponentSystem<TComponent>;
}
现在,我这里特定的代码块将引发错误,以及:
//*** blows up here as well ***(2)
ISystemManager sysMan = new SystemManager(); // defined elsewhere
sysMan.AddNewComponentToEntity<Tag, ITagSystem>(entity);
至于我收到错误,错误(1)是:
Cannot convert type 'TagSystem' to 'AComponentSystem<Tag>'
错误(2)低于:
The type 'ITagSystem' cannot be used as type parameter 'TComponentSystem' in the generic type or method 'ISystemManager.AddNewComponentToEntity<TComponent,TComponentSystem>(Entity)'. There is no implicit reference conversion from 'ITagSystem' to 'IComponentSystem<Tag>'.
现在,据我的问题去,它正是如此:
- 我为什么不能转换
TagSystem
到AComponentSystem<Tag>
?这看起来像一个有效的变形。 - 为什么
ITagSystem
不能转换为IComponentSystem<Tag>
?看起来标签应该仍然符合ITag,这是支持的。 - 有没有什么办法可以改变我的层次结构,同时保留我对这么多层抽象的需求?
谢谢任何人阅读本文并协助我。
注意:是的,这是针对EntityFramework驱动的游戏引擎。我主要将它作为自己的练习来构建,因此我可以为自己快速启动3D项目。是的,我之前已经构建了一些游戏项目,不,我对“完成”游戏不感兴趣,我只是修修补补,玩得开心。
啊对,泛型。我的道歉,我想不出正确的词汇,模板是第一个想到的。我会回去编辑帖子,实际上我根本没有太多的C++大师。 – Hondros