具有抽象实现的通用接口



我正在尝试在。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的构造函数中的任何参数都包括特定类型的NodeIDictionary,而不仅仅是实现INode的东西。例如,我稍后可能会创建一个名为GraphNode的具体类,并且我希望确保在构造函数中只使用GraphNode。

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

我希望能就如何处理这个问题提供一些建议。如果没有最佳解决方案,那么各种解决方案的优缺点是什么?

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

首先,由于INode<T>没有完全实现,代码也无法编译。你的接口为Neighbors定义了一个set方法,所以你的set必须是公共的,或者你必须显式地实现那个属性。

第二,假设你真的想限制你的构造函数把neighbors作为一个字典键接在Node<T>类上,而不是接口上,你能做的最快的事情就是把this.Neighbors改为
this.Neighbors = neighbors.ToDictionary(
    neighborDistance => (INode<T>)neighborDistance.Key,
    neighborDistance => neighborDistance.Value
);

必须这样做,因为通用IDictionary不是协变的。

最新更新