获取两种类型的最具体接口

本文关键字:接口 两种 类型 获取 | 更新日期: 2023-09-27 18:07:10

我试图获得两种类型实现的最具体的接口。获取接口列表相当容易:

var interfaces = leftType.GetInterfaces().Intersect(rightType.GetInterfaces());

然后,遍历列表并删除"包含"到其他接口中的接口:

var remaining = interfaces.ToDictionary(i => i, i => true);
foreach(var iface in interfaces)
    foreach(var subIface in iface.GetInterfaces())
        remaining.Remove(subIface);

然而,当试图获得int[]List<int>的最常用接口时,我得到了三个接口的列表:

  • IList(非通用)
  • IList<int>
  • IReadOnlyList<int>

首先,为什么IList<T>不实现非泛型IList,而IEnumerable<T>却实现了IEnumerable ?

那么,IReadOnlyList会引起一定的混淆。该名称暗示实现接口的容器禁止修改,但相反,其用法暗示容器允许读访问而不关心修改。但如果是这样,为什么IList<T>不实现IReadOnlyList<T>呢?

也许整个方法是不正确的,有一个更聪明的方法来检测最具体的接口?

获取两种类型的最具体接口

IList<T>不实现IList,因为IList<T>允许您传入对象。允许在这里使用非泛型接口将破坏类型安全性。
想象一下:

IList list = new List<WhateverClass>();
list.Add(new object()); // Runtime error because the type doesn't match

IEnumerable<T>只允许你取出对象,而不是传入对象(T是协变的)。您可以遍历IEnumerable<T>的元素,并像处理object一样处理所有项。所以IEnumerable<T>可以毫无问题地实现IEnumerable

同样,List<T>实现IReadOnlyList<T>的事实仅仅意味着List<T>实现了接口所要求的契约(这并没有明确禁止实际修改)。
如果您只需要对列表进行读访问,则可以将List<T>视为只读列表。