问题描述
IList
不继承 IList
其中 IEnumerable
继承 IEnumerable
.>
如果out
修饰符是唯一的原因,那么为什么大多数IList
的实现(例如Collection
,List
) 实现了 IList
接口.
所以任何人都可以说好的,如果该语句对于 IList
的所有实现都是正确的,那么在必要时直接将其转换为 IList
.但问题是虽然 IList
不继承 IList
所以不能保证每个 IList
对象都是 IList
.
此外,使用 如果 .NET 想要给 将 如您所见, 添加泛型,除其他原因外,是为了提供类型安全.例如,您不能将 Anders Hejlsberg,C# 的创造者之一,这样解释: 理想情况下,所有泛型集合接口(例如 事实证明,唯一可能的通用接口是 1) 从 .Net 4.5 开始,有 如果我可以从头开始重新设计 .Net 4.5,我会将列表接口拆分为只读协变接口 M42 集合 - 协变集合、列表和数组. If So any one can say OK, if that statements is true for all implementation of Moreover using If .NET wants to give flexibility that every implementation of Same problem occurs for casting As you note, Generics were added, among other reasons, to provide type safety. For example, you can't add an Anders Hejlsberg, one of the creators of C#, explains it like this: Ideally all of the generic collection interfaces (e.g. As it turns out, the only generic interface for which this is possible is 1) Since .Net 4.5 there are the If I could redesign .Net 4.5 from the ground up, I would have split the list interface into a read-only covariant interface M42 Collections - Covariant collections, lists and arrays.
这篇关于为什么通用 IList<>不继承非泛型 IList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2IList 显然不是解决方案,因为没有
out
修饰符泛型不能分配给较少继承的类;并且在这里创建 List 的新实例不是解决方案,因为有人可能希望将 IList
实际引用作为 IList
指针;并使用 List
代替 IList
实际上是一种糟糕的编程习惯,并不能达到所有目的.IList
的每个实现提供灵活性,不应该有非通用实现的契约(即 IList
),那么为什么他们没有不保留另一个实现泛型和非泛型版本的接口,也没有建议所有想要为泛型和非遗传项签约的具体类都应该通过该接口签约.ICollection
转换为 ICollection
并将 IDictionary
转换为 IDictionary
也会出现同样的问题>.IList
中的 T
不是 协变.根据经验:任何可以修改其状态的类都不能是协变的.原因是这些类通常具有将 T
作为其参数之一的类型的方法,例如void Add(T element)
.输入位置不允许使用协变类型参数.Elephant
添加到 Apple
的列表中.如果 ICollection
要扩展 ICollection
,那么您可以调用 ((ICollection)myApples).Add(someElephant)
而无需编译-时间错误,因为ICollection
有一个方法void Add(object obj)
,它似乎允许您将任何 对象添加到列表中,而在实践中你只能添加T
的对象.因此,ICollection
不会扩展 ICollection
并且 IList
不会扩展 IList
.>ICollection
、IList
)都将从它们的非泛型对应物继承,以便泛型接口实例可以可用于泛型和非泛型代码.IEnumerable
,因为只有 IEnumerable
是逆变的[sic1]:在IEnumerable
中,类型参数T
仅用于输出"位置(返回值)而不是输入"位置(参数).ICollection
和 IList
在输入和输出位置都使用 T
,因此这些接口是不变的.IEnumerable
是 co-variant IReadOnlyCollection
和 IReadOnlyList
协变接口.但是 IList
、ICollection
和许多列表和集合类没有实现或扩展它们.坦率地说,我发现它们不是很有用,因为它们只定义了 Count
和 this[int index]
.IList
,其中包括 Contains
和 IndexOf
,以及一个可变的不变接口 IMutableList
.然后你可以将 IList
转换为 IList.我在这里实现了这个:<块引用>
IList<T>
does not inherit IList
where IEnumerable<out T>
inherits IEnumerable
.out
modifier are the only reason then why most of the implementation of IList<T>
(e.g. Collection<T>
, List<T>
) implements IList
interface.IList<T>
then directly cast it to IList
when necessary. But problem is that though IList<T>
does not inherit IList
so it is not guaranteed that every IList<T>
object are IList
.IList<object>
is obviously not the solution because without out
modifier generics can not be assigned to a less inherit class; and creating new instance of List is not a solution here because someone may want actual reference of the IList<T>
as an IList
pointer; and use List<T>
insteed of IList<T>
is actually a bad programming practice and doesn't serve all purpose.IList<T>
should not have a contract of non-generic implementation (i.e. IList
) then why they didn't keep another interface which implement both generic and non-generic version and didn't suggest that all concrete class which want to contract for generic and non-genetic item should contract via that interface.ICollection<T>
to ICollection
and IDictionary<TKey, TValue>
to IDictionary
.T
in IList<T>
is not covariant. As a rule of thumb: any class that can modify its state cannot be covariant. The reason is that such classes often have methods that have T
as the type of one of their parameters, e.g. void Add(T element)
. And covariant type parameters are not allowed in input positions.Elephant
to a list of Apple
. If ICollection<T>
were to extend ICollection
, then you could call ((ICollection)myApples).Add(someElephant)
without a compile-time error, as ICollection
has a method void Add(object obj)
, which seemingly allows you to add any object to the list, while in practice you can only add objects of T
. Therefore, ICollection<T>
does not extend ICollection
and IList<T>
does not extend IList
.
ICollection<T>
, IList<T>
) would inherit from their non-generic counterparts such that generic interface instances could be used both with generic and non-generic code.IEnumerable<T>
, because only IEnumerable<T>
is contra-variant [sic1]: In IEnumerable<T>
, the type parameter T
is used only in "output" positions (return values) and not in "input" positions (parameters). ICollection<T>
and IList<T>
use T
in both input and output positions, and those interfaces are therefore invariant.IEnumerable<T>
is co-variant
IReadOnlyCollection<out T>
and IReadOnlyList<out T>
covariant interfaces. But IList<T>
, ICollection<T>
and many of the list and collection classes don't implement or extend them. Frankly, I find them not very useful, as they only define Count
and this[int index]
.
IList<out T>
that includes Contains
and IndexOf
, and a mutable invariant interface IMutableList<T>
. Then you could cast IList<Apple>
to IList<object>
. I implemented this here:
登录
关闭