在这篇文章的底部是一个解决方案的例子,尽管很明显这个例子是无效的,因为它使用了BaseNode和BaseEdge,但在继承时没有提供类型。
我尝试创建一个抽象图类,其中节点类和边类也必须是抽象的。每个类的单独实现将添加方法和属性,以及从基类实现抽象方法。
我有一个现有的解决方案,它只使用基本类型的一切,但我很快发现自己在一个混乱的造型。
只有图形类必须公开,尽管其他类可以公开,因此涉及嵌套在图形类中的节点和边类的解决方案是可以接受的。
有没有什么方法可以使所有属性都是正确的类型,而不会在系统中的任何地方进行昂贵的强制转换?更重要的是,实现类不必到处强制转换,但在这种情况下,性能肯定是一个问题(实际上是),所以我宁愿完全避免强制转换。
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();
}
Node的实现可能看起来像这样:
class ImplementedNode : BaseNode
{
public override float process()
{
foreach (ImplementedEdge edge in this.Inputs)
{
// Something
}
}
public bool getImplementationSpecificInfo()
{
return true;
}
}
3条答案
按热度按时间yjghlzjz1#
如果您愿意放松对
BaseEdge
和BaseNode
的约束,那么您可以像下面的示例中那样做。我已经介绍了接口
INode
和IEdge
,所以无论谁使用它都不允许创建BaseEdge
和BaseNode
的任何类型的具体子类。g6ll5ycj2#
更新
另一个答案,它提供了某种类型安全性。
这样就不会出现编译错误。
更新
这个答案不起作用。但是,我把它留在这里的评论,与它出现。
@NodeDear,我认为你最初的例子在
Graph
是通用的时候是正确的:在您为@marceln提供的示例中,
Graph
类不是泛型。因此,你必须做各种各样的铸造。但是对于generic版本:这允许从
Graph<TNode, TEdge>
派生的任何类型都具有强类型的节点和边,这正是OP所寻找的。jgovgodb3#
我找到了解决办法