我目前面临一个非常令人不安的问题:
interface IStateSpace<Position, Value>
where Position : IPosition // <-- Problem starts here
where Value : IValue // <-- and here as I don't
{ // know how to get away this
// circular dependency!
// Notice how I should be
// defining generics parameters
// here but I can't!
Value GetStateAt(Position position);
void SetStateAt(Position position, State state);
}
当你在这里时,IPosition
,IValue
和IState
都相互依赖。我怎么能逃脱这个?我想不出任何其他设计会绕过这种循环依赖,仍然准确描述我想要做的事情!
interface IState<StateSpace, Value>
where StateSpace : IStateSpace //problem
where Value : IValue //problem
{
StateSpace StateSpace { get; };
Value Value { get; set; }
}
interface IPosition
{
}
interface IValue<State>
where State : IState { //here we have the problem again
State State { get; }
}
基本上我有一个状态空间IStateSpace
,其中包含状态IState
。他们在州空间的位置由IPosition
给出。然后每个州都有一个(或多个)值IValue
。我正在简化层次结构,因为它比描述的要复杂一些。使用泛型定义此层次结构的想法是允许相同概念的不同实现(IStateSpace
将作为矩阵作为图形等实现。)
我能逃脱这个吗?你如何解决这类问题?在这些情况下使用哪种设计?
由于
答案 0 :(得分:5)
答案 1 :(得分:3)
问题是什么并不完全清楚 - 是的,你的泛型类型中存在循环依赖关系,但是可行。
我在Protocol Buffers中有类似的“问题”:我有“消息”和“建设者”,他们成对出现。所以接口看起来像这样:
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
和
public interface IBuilder<TMessage, TBuilder> : IBuilder
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
这当然很难看,但它确实有效。您希望能够表达您目前无法表达的内容?您可以看到我对此on my blog的一些看法。 (关于协议缓冲区的系列的第2和第3部分在这里是最相关的。)
(另外,如果您要在类型参数中添加T
前缀,它会使您的代码更加传统。目前看起来State
和Value
只是类。 )