使用泛型接口实现接口时使用兼容的具体类型 属性

Use a Compatible Concrete Type When Implementing Interface With a Generic Interface Property

有时您想要实现如下所示的接口:

public interface ITraversable<T> {

    List<T> Children { get; }

}

但有时您需要一个不同的集合 class,例如:

public interface ITraversable<T> {

    ObservableCollection<T> Children { get; }

}

但是你不想重复自己,所以你试试这个界面:

public interface ITraversable<T> {

    IEnumerable<T> Children { get; }

}

但是任何使用 List 或 ObservableCollection 的实现 class 都会出错:

错误 CS0738 'Tester' 没有实现接口成员 'ITraversable.Children'。 'Tester.Children' 无法实现 'ITraversable.Children' 因为它没有 'IEnumerable'.

的匹配 return 类型

是否可以创建一个具有通用接口 属性 的接口,供多个具体 class 实现使用?

这是我发现的一种实现单个接口的方法,该接口具有可以由多个具体实现的通用接口 类:

public interface ITraversable<T, out TEnumerable> where TEnumerable : IEnumerable<T> {

    TEnumerable Children { get; }

}

这允许您使用不同的 类 来使用 IEnumerable 的不同具体实现。

public class TestClass1 : ITraversable<TestClass1, List<TestClass1>> {

    public List<TestClass1> Children { get; }

}

public class TestClass2 : ITraversable<TestClass2, ObservableCollection<TestClass2>> {

    public ObservableCollection<TestClass2> Children { get; }

}

实现接口时,类型必须完全匹配。这就是为什么不能用 List 替换 IEnumerable 的原因,因为它们不是完全相同的类型。但是,如果您在接口上将确切类型指定为泛型参数,则可以精确匹配类型。

您可以在仍然满足 IEnumerable<T> 要求的情况下使用显式接口实现:

public interface ITraversable<T> {

    IEnumerable<T> Children { get; }

}

public class Implementer1<T>: ITraversable<T> {
    List<T> Children { get; }
    IEnumerable<T> ITraversable<T>.Children => Children;
}

public class Implementer2<T>: ITraversable<T> {
    ObservableCollection<T> Children { get; }
    IEnumerable<T> ITraversable<T>.Children => Children;
}

这样不会报有两个同名属性的错误,也不会造成无限递归,因为显式接口实现是隐藏的,除非你是通过接口访问它。