我们可以在接口定义中引用具体类型(无论它们是什么)吗?

本文关键字:是什么 类型 接口 定义 引用 我们 | 更新日期: 2023-09-27 18:03:34

我必须在某些类型的对象上添加Diff功能。我想提出一个接口,它将定义能够与其他相同类型的对象进行比较的对象。我们称之为IDiffable

interface IDiffable
{
 DiffDetails CompareWith(object other); 
}

现在的问题是,在CompareWith方法中,用户可以传递任何类型,包括那些实现了IDiffable的和那些没有的。让我们把它们限制在那些实现了IDiffable的。

interface IDiffable
{
 DiffDetails CompareWith(IDiffable other); 
}

现在剩下的最后一块拼图是,用户仍然可以传入不同类型的对象,而不是正在调用的对象。我怎么限制它呢?

这是一个我想要避免的例子。

internal class TypeA : IDiffable
{
 internal DiffDetails CompareWith(IDiffable obj) 
 {
   // compare here
 }
}
internal class TypeB : IDiffable
{
 internal DiffDetails CompareWith(IDiffable obj) 
 {
   // compare here
 }
}

我想避免下面的

var a = new TypeA();
var b = new TypeB();
var diff = a.CompareWith(b); // incorrect usage, how to avoid this?

我想只允许以下

var a = new TypeA();
var b = new TypeB();
var another_a = new TypeA();
var diff = a.CompareWith(another_a); // Correct usage

我们可以在接口定义中引用具体类型(无论它们是什么)吗?

您可以使用泛型来做到这一点。

interface IDiffable<T>
{
    string Diff(IDiffable<T> obj);
}
class DiffA : IDiffable<DiffA>
{
    public string Diff(IDiffable<DiffA> obj)
    {
        return "Diffable A";
    }
}
class DiffB : IDiffable<DiffB>
{
    public string Diff(IDiffable<DiffB> obj)
    {
        return "Diffable B";
    }
}

这有点混乱,因为你必须在类定义中声明你的类型两次。当您开始使用子类型或使用泛型进行更复杂的限制时,它也会很快变得笨拙。

但是上面的代码达到了你想要的效果。

static void Main(string[] args)
{
    var a = new DiffA();
    var b = new DiffB();
    a.Diff(a); // Runs fine
    a.Diff(b); // Compiler error
}