为什么((IList )数组).ReadOnly = True但是((IList)数组).ReadOnly = False?

我知道在.NET中,所有数组都派生自System.Array,System.Array类实现IListICollectionIEnumerable 。 实际数组类型还实现IListICollectionIEnumerable

这意味着如果你有一个String[] ,那么String[]对象也是一个System.Collections.IList和一个System.Collections.Generic.IList ;.

不难看出为什么那些IList会被认为是“ReadOnly”,但令人惊讶的是……

 String[] array = new String[0]; Console.WriteLine(((IList)array).IsReadOnly); // True Console.WriteLine(((IList)array).IsReadOnly); // False! 

在这两种情况下,尝试通过Remove()RemoveAt()方法删除项会导致NotSupportedException。 这表明两个表达式都对应于ReadOnly列表,但IList的ReadOnly属性不会返回预期值。

怎么会?

来自MSDN :

Array实现IsReadOnly属性,因为System.Collections.IList接口需要它。 只读数组不允许在创建数组后添加,删除或修改元素。

如果需要只读集合,请使用实现System.Collections.IList接口的System.Collections类。

如果将数组转换或转换为IList接口对象,则IList.IsReadOnly属性将返回false。 但是,如果将数组转换或转换为IList 接口,则IsReadOnly属性将返回true。

此处为只读意味着无法修改数组中的项,这就是它返回false的原因。

另外看看Array.IsReadOnly不一致,具体取决于接口实现 。

这看起来像一个普通的错误:

  • 它显然不是只读的,因为索引器允许它被修改
  • 没有执行到任何其他类型对象的转换

请注意,您不需要强制转换 – 存在隐式转换:

 using System; using System.Collections.Generic; class Test { static void Main() { string[] array = new string[1]; IList list = array; Console.WriteLine(object.ReferenceEquals(array, list)); Console.WriteLine(list.IsReadOnly); list[0] = "foo"; Console.WriteLine(list[0]); } } 

ICollection.IsReadOnlyIList从中inheritance属性) 记录为:

只读集合不允许在创建集合后添加,删除或修改元素。

虽然数组不允许添加或删除元素,但它显然允许修改。