这可能吗?当我编译时,我得到一个错误,即使用约束
,也无法将Component转换为TComponentpublic interface IComponent<TKey, TComponent> where TComponent : IComponent<TKey, TComponent>
{
TComponent Parent { get; }
void Register(TKey key, TComponent component);
void RegsiterWith(TKey key, TComponent component);
}
public class Component<TKey, TComponent> : IComponent<TKey, TComponent> where TComponent : IComponent<TKey, TComponent>
{
private TComponent _parent;
public void Register(TKey key, TComponent component)
{
component.RegsiterWith(key, this);
}
public void RegsiterWith(TKey key, TComponent component)
{
component.Register(key, this);
}
public TComponent Parent { get { return _parent; } }
}
答案 0 :(得分:8)
失败的原因是因为TComponent
实际上可能是IComponent<TKey, TComponent>
的某些其他实现。仅仅因为Component
实现了接口并不意味着没有别的可以:)
这方面的一个方法是更改界面:
public interface IComponent<TKey, TComponent>
where TComponent : IComponent<TKey, TComponent>
{
TComponent Parent { get; }
void Register(TKey key, IComponent<TKey, TComponent> component);
void RegsiterWith(TKey key, IComponent<TKey, TComponent> component);
}
在你的情况下我是否可行,我不知道,但它肯定会避免类型问题。
另一个选择是投射this
作为消费者的建议。这可能在执行时失败,但实际上除非你做创建一个替代实现,否则它不会。这有点令人讨厌,在使用泛型时必须施放,但偶尔会发生。
编辑:这是一个如何出错的例子:
public class Other : IComponent<string, Other>
{
// Implement interface
}
现在如果您创建Component<string, Other>
会怎样?它满足约束条件但没有问题......但Component
不是Other
...
现在你可以改变你的约束:
public class Component<TKey, TComponent> : IComponent<TKey, TComponent>
where TComponent : Component<TKey, TComponent>
即。约束TComponent
Component
而不是IComponent
。但仍有问题:
public class FooComponent : Component<string, FooComponent> {}
public class BarComponent : Component<string, FooComponent> {}
在这里,您可能希望BarComponent
拥有TComponent
,但它有一个不同的组件。你到目前为止所显示的代码可能还可以,但这种怪癖可能会妨碍其他目标。值得考虑......
哦,如果你很高兴Component
密封,那么改变的约束 就足够了(我想!)。
答案 1 :(得分:0)
演员如何:
public void Register(TKey key, TComponent component)
{
component.RegsiterWith(key, (TComponent)this);
}