Gre*_*ech 5 .net .net-3.5 c#-3.0
一个类型数组同时实现System.Collections.IList和System.Collections.Generic.ICollection<T>接口,都有自己的IsReadOnly特性.但到底是怎么回事?
var array = new int[10];
Console.WriteLine(array.IsReadOnly); // prints "False"
var list = (System.Collections.IList)array;
Console.WriteLine(list.IsReadOnly); // prints "False"
var collection = (System.Collections.Generic.ICollection<int>)array;
Console.WriteLine(collection.IsReadOnly); // prints "True"
Run Code Online (Sandbox Code Playgroud)
该IList阵列的视图表现为我预计,返回相同的阵列本身,但是ICollection<T>该阵列的视图返回true.
这种行为有没有合理的解释,还是编译器/ CLR错误?(如果是后者,我会感到非常惊讶,因为你会想象之前会发现这种情况,但这是违反直觉的,我无法想到解释可能是什么......).
我正在使用C#3.0/.NET 3.5 SP1.
IList是ICollection接口的后代,是所有非泛型列表的基本接口.IList实现分为三类:只读,固定大小和可变大小.无法修改只读IList.固定大小的IList不允许添加或删除元素,但它允许修改现有元素.可变大小的IList允许添加,删除和修改元素.
ICollection <T>接口没有索引器,因此固定大小的ICollection <T>会自动只读 - 无法修改现有项目.
可能ICollection <T> .IsFixedSize是一个比ICollection <T> .IsReadOnly更好的属性名,但两者都暗示相同的东西 - 不可能添加或删除元素,即与IList.IsFixedSize相同.
数组是固定大小的列表,但由于元素可以修改,因此不是只读的.
作为ICollection <T>,它是只读的,因为ICollection <T>无法修改元素.
这可能看起来令人困惑,但它是一致和合乎逻辑的.
稍微不一致的是,通用IList <T>接口具有从ICollection <T>继承的IsReadOnly属性,因此其语义与非通用IList.IsReadOnly不同.我想设计师已经意识到这种不一致性,但由于向后兼容的原因,他们无法返回并更改非通用IList的语义.
总而言之,IList可以是:
可变大小.
IList.IsFixedSize = false
IList.IsReadOnly = false
ICollection <T> .IsReadOnly = false
固定大小(但可以修改元素,例如数组)
IList.IsFixedSize = true
IList.IsReadOnly = false
ICollection <T> .IsReadOnly = true
只读(元素无法修改)
IList.IsFixedSize = true
IList.IsReadOnly = true
ICollection <T> .IsReadOnly = true