I know that in .NET all arrays derive from System.Array and that the System.Array class implements IList
, ICollection
and IEnumerable
. Actual array types also implement IList<T>
, ICollection<T>
and IEnumerable<T>
.
This means that if you have, for example, a String[]
, then that String[]
object is also a System.Collections.IList
and a System.Collections.Generic.IList<String>
;.
It's not hard to see why those IList's would be considered "ReadOnly", but surprisingly...
String[] array = new String[0];
Console.WriteLine(((IList<String>)array).IsReadOnly); // True
Console.WriteLine(((IList)array).IsReadOnly); // False!
In both cases, attempts to remove items via the Remove()
and RemoveAt()
methods results in a NotSupportedException. This would suggest that both expressions correspond to ReadOnly lists, but IList's ReadOnly
property does not return the expected value.
How come?
This looks like a plain bug to me:
Note that you don't need to cast - there's an implicit conversion:
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
(which IList<T>
inherits the property from) is documented as:
A collection that is read-only does not allow the addition, removal, or modification of elements after the collection is created.
While an array doesn't allow the addition or removal of elements, it clearly does allow modification.
See more on this question at Stackoverflow