C# 具有约束层次结构的泛型
我目前面临一个非常令人不安的问题:C# 具有约束层次结构的泛型,c#,generics,oop,circular-dependency,C#,Generics,Oop,Circular Dependency,我目前面临一个非常令人不安的问题: interface IStateSpace<Position, Value> where Position : IPosition // <-- Problem starts here where Value : IValue // <-- and here as I don't { // know how
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);
}
基本上我有一个状态空间IStateSpace
,里面有状态IState
。它们在状态空间中的位置由i位置给出。然后,每个状态都有一个(或多个)值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; }
}
然后您可以创建具体的实现
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;
}
}
现在您可以决定在需要IStateSpace
实例的地方使用MatrixStateSpace
或GraphStateSpace
实例。当然,所有其他类型的情况也是如此
实现中最具挑战性的部分是您必须创建新实例的时候。例如,IStateSpace
中可能定义了一个方法IState AddNewState()
。IStateSpace
的任何具体实现都面临创建IState
实例的问题(理想情况下),而不知道实现IState
的任何具体类型。这就是工厂、依赖注入和相关概念发挥作用的原因。我看不出您想要实现什么-为什么要使用泛型将具体类型强制到接口中?这似乎完全违背了接口的意图——不使用具体类型。以下非通用定义有什么问题
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; }
}
然后您可以创建具体的实现
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;
}
}
现在您可以决定在需要IStateSpace
实例的地方使用MatrixStateSpace
或GraphStateSpace
实例。当然,所有其他类型的情况也是如此
实现中最具挑战性的部分是您必须创建新实例的时候。例如,IStateSpace
中可能定义了一个方法IState AddNewState()
。IStateSpace
的任何具体实现都面临创建IState
实例的问题(理想情况下),而不知道实现IState
的任何具体类型。这是工厂、依赖注入和相关概念发挥作用的结果。问题是什么还不完全清楚-是的,泛型类型中存在循环依赖,但这是可行的
我有一个类似的“问题”:我有“消息”和“构建器”,它们成对出现。因此,接口如下所示:
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
公共接口IMessage
where-TMessage:IMessage
制造商:IBuilder
及
公共接口IBuilder:IBuilder
where-TMessage:IMessage
制造商:IBuilder
这确实很难看,但它很管用。你想表达什么是你目前无法表达的?你可以看到我对此的一些想法。(关于协议缓冲区的系列文章的第2部分和第3部分在这里最为相关。)
(顺便说一句,如果在类型参数中添加T
前缀,会使代码更加常规。目前看来State
和Value
只是类。)问题不完全清楚-是的,泛型类型中存在循环依赖,但这是可行的
我有一个类似的“问题”:我有“消息”和“构建器”,它们成对出现。因此,接口如下所示:
public interface IMessage<TMessage, TBuilder>
where TMessage : IMessage<TMessage, TBuilder>
where TBuilder : IBuilder<TMessage, TBuilder>
公共接口IMessage
where-TMessage:IMessage
制造商:IBuilder
及
公共接口IBuilder:IBuilder
where-TMessage:IMessage
制造商:IBuilder
这确实很难看,但它很管用。你想表达什么是你目前无法表达的?你可以看到我对此的一些想法。(关于协议缓冲区的系列文章的第2部分和第3部分在这里最为相关。)
(另一方面,如果在类型参数中添加T
前缀,则会使代码更为常规。目前看来State
和Value
只是类。)