“覆盖” Add 方法以使其接收更具体的类型不会满足您的接口所暗示的合同。
你说Container接口有这些方法:
void Add(IComponent component);
void Add(IComponent component, string name);
但是你只想允许 EntityContainer 实例(实现 IComponent),所以基本上你想要这个:
void Add(EntityComponent component);
void Add(EntityComponent component, string name);
你不能像这样实现(甚至在语义上)Container 接口,因为在你的接口中你说你可以添加任何实现 IComponent 的元素。你正在改变原来的合同!
正如 Morten 在评论中指出的那样,您可以执行以下操作:
class EntityContainer : Container {
void Add(IComponent component) {
var entityComponent = component as EntityComponent;
if(entityComponent == null)
throw new InvalidOperationException("Can only add EntityComponent instances");
// Actual add...
}
// Other methods..
}
但我建议你不要这样做。违反接口暗示的契约应该是例外,而不是规则。此外,如果你这样做,你无法知道容器真正期望什么,直到运行时。这不是一种直观的行为,它很可能会导致微妙的问题。如果您只想接受特定类型的组件,则可以使用泛型。这样,你不仅可以应用你想要的约束,还可以获得强类型,并且你的意图会更清晰。它看起来像这样:
interface Container<T> where T : IComponent {
void Add(T component);
void Add(T component, string name);
}
这意味着您的容器将保存指定类型的元素,但它应该实现(或扩展,如果它是一个类)接口 IComponent。所以你不能创建一个Container<Object>
,因为它没有实现 IComponent。
您的 EntityContainer 将如下所示:
class EntityContainer : Container<EntityComponent> {
void Add(EntityComponent component) {
// Actual add...
}
// Other methods..
}