在本文的底部是一个解决方案的外观示例,尽管很明显这个示例是无效的,因为它在继承时使用了basenode和baseedge而没有提供类型。
我试图创建一个抽象图类,其中node类和edge类都必须是抽象的。每个类的单独实现将添加方法和属性,并实现基类中的抽象方法。
我有一个现有的解决方案,它只使用基本类型的一切,但我很快发现我自己在一个混乱的铸造。
只有Graph类必须公开,尽管其他类可以公开,因此可以接受包含嵌套在Graph类中的节点类和边缘类的解决方案。
是否有任何方法可以将其结构化,以便所有属性都是正确的类型,而不必在系统中的任何位置进行昂贵的强制转换?更重要的是,实现类不必到处强制转换,但在这种情况下(实际上是这样),性能绝对是一个问题,所以我宁愿完全避免强制转换。
abstract class Graph<TNode, TEdge>
where TNode : BaseNode<TEdge>
where TEdge : BaseEdge<TNode>
{
TNode root;
List<TNode> nodes;
List<TEdge> edges;
public abstract float process();
}
abstract class BaseNode<TEdge>
// THIS HERE IS THE PROBLEM
where TEdge : BaseEdge
{
List<TEdge> inputs;
public List<TEdge> Inputs
{
get
{
return inputs;
}
}
public abstract float process();
}
abstract class BaseEdge<TNode>
// THIS HERE IS THE PROBLEM
where TNode : BaseNode
{
TNode from;
TNode to;
public TNode To
{
get
{
return to;
}
}
public TNode From
{
get
{
return from;
}
}
public abstract float process();
}
Marceln希望看到我现有的实现,所以就在这里。没有泛型也是一样的。
abstract class Graph
{
BaseNode root;
List<BaseNode> nodes;
List<BaseEdge> edges;
public abstract float process();
}
abstract class BaseNode
{
List<BaseEdge> inputs;
public List<BaseEdge> Inputs
{
get
{
return inputs;
}
}
public abstract float process();
}
abstract class BaseEdge
{
BaseNode from;
BaseNode to;
public BaseNode To
{
get
{
return to;
}
}
public BaseNode From
{
get
{
return from;
}
}
public abstract float process();
}
节点的实现可能如下所示:
class ImplementedNode : BaseNode
{
public override float process()
{
foreach (ImplementedEdge edge in this.Inputs)
{
// Something
}
}
public bool getImplementationSpecificInfo()
{
return true;
}
}
最佳答案
如果您愿意放松对BaseEdge
和BaseNode
的约束,那么您可以执行如下示例中的操作。
我已经介绍了接口INode
和IEdge
,所以不允许任何人使用任何类型创建BaseEdge
和BaseNode
的具体子类。
public interface INode
{
}
public interface IEdge
{
}
public abstract class Graph<TNode, TEdge>
where TNode : BaseNode<TEdge>
where TEdge : BaseEdge<TNode>
{
public TNode Root { get; set; }
public List<TNode> Nodes { get; set; }
public List<TEdge> Edges { get; set; }
}
public abstract class BaseNode<TEdge> : INode where TEdge: IEdge
{
List<TEdge> inputs;
public List<TEdge> Inputs
{
get
{
return inputs;
}
}
public abstract float process();
}
public abstract class BaseEdge<TNode> : IEdge where TNode: INode
{
TNode from;
TNode to;
public TNode To
{
get
{
return to;
}
}
public TNode From
{
get
{
return from;
}
}
public abstract float process();
}
public class ConcreteNode : BaseNode<ConcreteEdge>
{
public override float process()
{
return 0;
}
}
public class ConcreteEdge : BaseEdge<ConcreteNode>
{
public override float process()
{
return 0;
}
}
public class ConcreteGraph : Graph<ConcreteNode, ConcreteEdge>
{
}