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

时间:2014-10-20 21:36:55

标签: c# .net arrays generics

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

这意味着,如果您有String[],那么String[]对象也是System.Collections.IListSystem.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属性不会返回预期值。

怎么回事?

2 个答案:

答案 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