如何定义一个接口,以确保它的孩子和父母是与定义的接口相同的类型
所以我有一个工作的解决方案,但我只是不确定我是否过于复杂。如何定义一个接口,以确保它的孩子和父母是与定义的接口相同的类型
假设我们有以下两个接口:
public interface IPrototype
{
Guid Id { get; set; }
string Name { get; set; }
}
public interface IHierarchicalPrototype : IPrototype
{
IHierarchicalPrototype Parent { get; set; }
IList<IHierarchicalPrototype> Children { get; set; }
}
现在假设许多实现的IHierarchicalPrototype
存在,例如IEntityPrototype
或IFieldPrototype
。
在上述定义中的Parent
可以是任何IHierarchicalPrototype
和IEntityPrototype
的Children
列表可以包含任何IHierarchicalPrototype
。
我想确定的是,IHierarchicalPrototype
只能包含自己类型的孩子。因此,IEntityPrototype
的Children
的类型为IList<IEntityPrototype>
,而Parent
的类型为IEntityPrototype
。
一个解决方案是实现为每个从IHierarchicalPrototype
派生原型Children
和Parent
但有如此一个简单的方法!
我想出的是一个有泛型的解决方案。
而不是定义
interface IEntityPrototype : IHierarchicalPrototype {}
我可以用这样的泛型定义它的:
interface IEntityPrototype : IHierarchicalPrototype<IEntityPrototype>
我不能让虽然摆脱多余的泛型类型参数的。我想泛型类型参数总是匹配我目前定义界面,实际上只需要上述如果我想搭配的原型是这样(我不)
// this will never happen!
interface IEntityPrototype : IHierarchicalPrototype<IFieldPrototype>
这里也是一般定义的IHierarchicalPrototype
接口
public interface IHierarchicalPrototype<THierarchical> : IPrototype
where THierarchical : IHierarchicalPrototype<THierarchical>
{
IHierarchicalPrototype<THierarchical> Parent { get; }
IList<IHierarchicalPrototype<THierarchical>> Children { get; }
}
您可以想出任何替代或更优雅的解决方案?
感谢@Damien_The_Unbeliever我现在知道什么我已实施实际上是一个名为couriously recurring template pattern(CRTP)模式。
Eric Lippert和Zp Bappi这两个人写了关于此更多的人谁感兴趣。
[I] n的练习使用这种模式确实务实解决是很难的C#,否则建模方法的问题时,有次。[...]原因之一,人们为什么要做到这一点,是执行类型层次结构中的特定约束。
这个确切的原因是我试图用我的代码实现的。
我对Lippert的帖子也提到了对CRTP的怀疑。他建议
你实现这种奇怪的模式 在C#之前觉得很辛苦
的面条
- ,因为它实际上并没有强制约束,你认为它
- 这很简单,因为它烤人谁读码
如果我明白你的要求,那么这可能会有所帮助。
public interface IPrototype
{
Guid Id { get; set; }
string Name{ get; set; }
}
public interface IHierarchicalPrototype<T> : IPrototype where T:IPrototype
{
T Parent{ get; }
IList<T> Children { get; }
}
这是不正确的。 'IEntityPrototype接口:IHierarchicalPrototype
您可能需要阅读埃里克利珀的[奇妙而又奇妙(HTTPS://blogs.msdn.microso ft.com/ericlippert/2011/02/03/curiouser-and-curiouser/),它讨论了“奇怪的循环模板模式”,以及它为什么不能在C#中使用它。 –
@Damien_The_Unbeliever哇,那*非常*快。非常感谢,我不知道我所实施的实际上是一种模式。非常有见地。我的确在问自己,我的实施在未来的好处是否会超过它的缺点。虽然我看不出这种模式的全部垮台,但我现在可以理解为什么。如果你写出更彻底的答案,我会很乐意接受它。 –
有些事情你不能执行.... –