为什么 .Net FCL 在 List<T> 类中同时实现泛型和非泛型接口 IList 和 IList<T>?

3
在.NET中,列表的实现方式如下。我很惊讶为什么他们同时在类中实现了通用和非通用接口。
[Serializable]
public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>,
IList, ICollection, IEnumerable {
public List();
public void Add(T item);
public Int32 BinarySearch(T item);
public void Clear();
public Boolean Contains(T item);
public Int32 IndexOf(T item);
public Boolean Remove(T item);
public void Sort();
public void Sort(IComparer<T> comparer);
public void Sort(Comparison<T> comparison);
public T[] ToArray();
public Int32 Count { get; }
public T this[Int32 index] { get; set; }
}

2
为什么不可以呢? IListIList<T> 并非可互换使用,可以说它们之间并不相互包含。 - Maarten
1
请注意,IList 方法和属性是显式实现,因此只有在将列表显式类型化为 IList 时才会使用它们。这主要是为了向后兼容性,以确保您可以在使用早于 .NET 泛型之前制作的库时使用通用的 List<T> :) - Luaan
2个回答

3
Microsoft极力让.NET程序员忘记COM的存在,但这并不符合事实。COM依然活跃并且是Windows上主要的交互技术。例如,商店和电话应用中的Modern UI在幕后完全基于COM实现,虽然非常隐蔽,但在编写C#应用程序时几乎无法发现你实际上正在使用COM,除了轻松地处理用Javascript或C++编写的代码似乎是黑魔法一样。
.NET中的通用类型是一个交互问题,其是纯.NET实现的细节,其他非.NET语言完全不了解。因此,List<T>不能是[ComVisible(true)]。
IList、ICollection和IEnumerable则拯救了我们,它们是可见并且可由在Windows上使用几乎任何语言编写的代码使用的接口。

1
这是一个兼容性问题。许多组件(例如UI库中的组件)使用非泛型的IList,因为在这里使用泛型版本并不必要,而且通常也不可取。
考虑一下这个WPF示例:
var list = new List<MyDataType>();
var collectionView = new ListCollectionView(list);

假设 List<T> 没有实现 IList,那么你就不能在这个示例中使用它。此外,请想象 ListCollectionView 必须是泛型,并尝试实现它。

5
使用通用版本并不一定是必需的,而且通常也不是理想的选择。我不确定是否同意这种说法。主要是因为.NET 1.0不支持泛型,才会存在向后兼容性问题。 - Yuval Itzchakov
@YuvalItzchakov:在我的示例中,通用的ListCollectionView<T>最终会导致例如ListBox<T>。你确定这就是我们需要的全部吗? :) - Dennis
我不确定我理解你的评论:\ - Yuval Itzchakov
@YuvalItzchakov: 泛型需要类型参数。在WPF中,ListCollectionView用于表示其项的ItemsControl中。要使用任何TItemsControl代码中实例化ListCollectionView<T>,我们需要ItemsControl<T>(最终,ListBox<T>, 因为它是从ItemsControl继承而来)。泛型控件?... 有什么作用吗? - Dennis
为了在以后访问该控件的项目时获得正确的类型“T”。 - Yuval Itzchakov
1
问题在于您不需要强类型访问控件项。这个任务可以通过基于反射的数据绑定来解决。 - Dennis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接