我知道在.NET中,所有数组都派生自System.Array,System.Array类实现IList
,ICollection
和IEnumerable
。实际数组类型还实现IList<T>
,ICollection<T>
和IEnumerable<T>
。
这意味着,如果您有String[]
,那么String[]
对象也是System.Collections.IList
和System.Collections.Generic.IList<String>
;。
不难看出为什么那些IList会被认为是&#34; ReadOnly&#34;,但令人惊讶的是......
String[] array = new String[0];
Console.WriteLine(((IList<String>)array).IsReadOnly); // True
Console.WriteLine(((IList)array).IsReadOnly); // False!
在这两种情况下,尝试通过Remove()
和RemoveAt()
方法删除项目都会导致NotSupportedException。这表明两个表达式都对应于ReadOnly列表,但IList的ReadOnly
属性不会返回预期值。
怎么回事?
答案 0 :(得分:11)
这对我来说似乎是一个普通的错误:
请注意,您不需要强制转换 - 存在隐式转换:
using System;
using System.Collections.Generic;
class Test
{
static void Main()
{
string[] array = new string[1];
IList<string> list = array;
Console.WriteLine(object.ReferenceEquals(array, list));
Console.WriteLine(list.IsReadOnly);
list[0] = "foo";
Console.WriteLine(list[0]);
}
}
ICollection<T>.IsReadOnly
(其中IList<T>
继承了该属性)的格式为documented:
在创建集合后,只读集合不允许添加,删除或修改元素。
虽然数组不允许添加或删除元素,但显然 允许修改。
答案 1 :(得分:11)
来自MSDN:
Array实现了IsReadOnly属性,因为它是必需的 System.Collections.IList接口。一个只读的数组 之后不允许添加,删除或修改元素 数组已创建。
如果需要只读集合,请使用System.Collections类 实现System.Collections.IList接口。
如果将数组转换或转换为IList接口对象,则 IList.IsReadOnly属性返回false。但是,如果你施放或 将数组转换为IList&lt; T&gt;接口,IsReadOnly属性 返回true。
这里只读意味着数组中的项目无法修改,这就是它返回false的原因。
另请查看Array.IsReadOnly inconsistent depending on interface implementation。