'覆蓋'Add方法,因此它接收更具體的類型將不會履行您的界面所暗示的合同。
你說的那個容器界面有以下方法:
void Add(IComponent component);
void Add(IComponent component, string name);
但你希望只允許EntityContainer相關實例(它們實現IComponent的),所以基本上你想要這個:
void Add(EntityComponent component);
void Add(EntityComponent component, string name);
你可以't實現(甚至語義上)這樣的Container接口,因爲在你的接口中,你說你可以添加任何實現IComponent的元素。你正在改變原來的合同!
由於莫滕在評論中指出,你可以做這樣的事情:
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..
}
但我建議你不這樣做。打破界面所暗示的合同應該是例外,而不是規則。另外,如果你這樣做了,你就不知道Container在運行之前真正期望什麼。這不是一種直觀的行爲,它很可能會導致微妙的問題。如果您只想接受特定類型的組件,則可以使用泛型。通過這種方式,你不僅可以應用你想要的約束,你也將獲得強大的打字,並且你的意圖會更加清晰。它看起來像這些:
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..
}
是否有可能使基類的通用? – Ryan
在你的'Add'方法中,如果傳遞的類型不兼容,則失敗:'if(!(component is EntityContainer))throw new InvalidArgumentException(「component」);'。一旦一個類通過,你可以將它轉換爲預期的類型:'var c = component as EntityContainer;'並且從那裏使用它,就像你直接接收它一樣。 –
這些是默認的System.ComponentModel.Component和.Container的更具體的實現,所以我傾向於「不」。 –