与抽象实现的通用接口

时间:2014-08-25 01:32:28

标签: c# asp.net inheritance design-patterns graph

我正在尝试在.NET中实现一些用于有趣和个人教育的图搜索算法。对于我的实现,我选择从一个实现以下接口的Node类开始:

public interface INode<T>
{
    T Data { get; }

    IDictionary<INode<T>, int> Neighbors { get; set; }
}

节点包含一些类型为T的Data,以及与它们的整数距离共享边缘的节点字典。然后我想我可以创建一个抽象的Node类:

public abstract class Node<T> : INode<T>
{
    public T Data { get; private set; }

    public IDictionary<INode<T>, int> Neighbors { get; private set; }

    public Node(T data, IDictionary<Node<T>, int> neighbors)
    {
        this.Data = data;

        this.Neighbors = neighbors;
    }
}

上述情况并不奏效,因为neighborsNeighbors不匹配。我希望Node的构造函数中的任何参数都包含该IDictionary特定类型的Node,而不仅仅是实现INode的内容。例如,我稍后可能会创建一个名为GraphNode的具体类,我想确保在构造函数中只使用GraphNodes。

要解决这个问题,我可以简单地将IDictionary Neighbors从INode中取出并放入抽象的Node类中。虽然使用像FakeItEasy这样的框架,这可能会限制我稍后测试该类的能力,而且我不确定它可能会产生什么其他影响。

我很欣赏一些关于如何解决这个问题的建议。如果没有最佳解决方案,那么各种解决方案的优缺点是什么?

1 个答案:

答案 0 :(得分:2)

根据给定的代码,您可以做两件事来进行编译。

首先,代码也无法编译,因为INode<T>未完全实现。您的界面为set定义了Neighbors方法,因此您的set必须是公开的,否则您必须明确实现该属性。

其次,假设你真的想限制你的构造函数把neighbors作为一个键入Node<T>类的字典,而不是接口,你可以做的最快的事情来加载{{1将行更改为

this.Neighbors

必须这样做,因为通用this.Neighbors = neighbors.ToDictionary( neighborDistance => (INode<T>)neighborDistance.Key, neighborDistance => neighborDistance.Value ); is not covariant