dev*_*ium 1 c# oop generics circular-dependency
我目前面临一个非常令人不安的问题:
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);
}
Run Code Online (Sandbox Code Playgroud)
正如你到这里,既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; }
}
Run Code Online (Sandbox Code Playgroud)
基本上我有一个状态空间IStateSpace,IState里面有状态.他们在州空间的位置由一个人给出IPosition.然后每个州都有一个(或多个)值IValue.我正在简化层次结构,因为它比描述的要复杂一些.使用泛型定义此层次结构的想法是允许相同概念的不同实现(IStateSpace将作为矩阵作为图形等实现).
我可以逃脱这个吗?你如何解决这类问题?在这些情况下使用哪种设计?
谢谢
我无法看到你想要实现的目标 - 为什么你想通过使用泛型强制将具体类型强加到你的接口中?这似乎完全违背了接口的意图 - 不使用具体类型.以下非泛型定义有什么问题?
public interface IStateSpace
{
IState GetStateAt(IPosition position);
void SetStateAt(IPosition position, IState state);
}
public interface IState
{
IStateSpace StateSpace { get; }
IValue Value { get; set; }
}
public interface IPosition
{
}
public interface IValue
{
IState State { get; }
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以创建具体的实现.
internal class MatrixStateSpace : IStateSpace
{
IState GetStateAt(IPosition position)
{
return this.Matrix[position];
}
void SetStateAt(IPosition position, IState state)
{
this.Matrix[position] = state;
}
}
internal class GraphStateSpace : IStateSpace
{
IState GetStateAt(IPosition position)
{
return this.Graph.Find(position).State;
}
void SetStateAt(IPosition position, IState state)
{
this.Graph.Find(position).State = state;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以决定使用MatrixStateSpace或需要GraphStateSpace实例的IStateSpace实例.当然,对于所有其他类型也是如此.
实现的挑战在于您必须创建新实例.例如,可能有一个IState AddNewState()定义的方法IStateSpace.任何具体的实现都IStateSpace面临着在IState不知道任何具体类型实现的情况下创建实例(理想情况)的问题IState.这是工厂,依赖注入和相关概念发挥作用.