具有接口约束的通用类与实现接口的类

Jay*_*cee 3 c# generics interface

最近我实现了一个Trie数据结构,并确定节点可以存储不同类型的数据或者实现变化,所以我去了Node<T>.然后当我进入构建Trie的算法时,我意识到它需要更多关于Node的知识,所以我限制泛型类使用INode接口.这允许更大的灵活性,但在泛型类的上下文中感觉错误.

通用类对实现接口的类具有不同的用例.例如,List<T>- 算法可以在不依赖于一组相关抽象的情况下工作.实现接口的类可能需要多态/ DI,但接口将更加专业化.

在什么情况下其他人应用泛型类T,其中T可以实现更专业的接口?

我认为当T不需要公开操作/数据时会使用泛型类,虽然我可以看到在T实现IDisposable或其他更通用的接口时可以使用泛型类.

澄清这些要点有什么帮助吗?

das*_*ght 5

当面临选择使用具有接口约束的泛型而非使用接口类型的非泛型时,我将仅在通用作为泛型参数传递的某些或所有类型为值类型的情况下使用泛型+接口.这将阻止我的实施在处理我的structs 时需要昂贵的装箱和拆箱.

例如,如果接口碰巧是IComparable,我肯定更喜欢具有约束的泛型,因为它可以让我在使用基元时避免装箱.

请注意,为泛型类提供功能的另一种方法是将委托与值一起传递.例如,如果您打算做这样的事情

interface IScoreable {
    decimal GetScore(object context);
}
class Node<T> where T : IScoreable {
    ...
    void DoSomething(T data) {
        var score = data.GetScore(someContext);
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

你也可以这样做:

class Node<T> {
    private Func<T,object,decimal> scorer;
    public Node(Func<T,object,decimal> scorer) {
        this.scorer = scorer;
    }
    ...
    void DoSomething(T data) {
        var score = scorer(data, someContext);
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

第二种解决方案允许您将评分功能与正在评分的类型"解耦",但代价是让调用者编写更多代码.