在本文的底部是一个解决方案的外观示例,尽管很明显这个示例是无效的,因为它在继承时使用了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;
    }
}

最佳答案

如果您愿意放松对BaseEdgeBaseNode的约束,那么您可以执行如下示例中的操作。
我已经介绍了接口INodeIEdge,所以不允许任何人使用任何类型创建BaseEdgeBaseNode的具体子类。

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>
{

}

07-24 09:37