This question already has an answer here:
这个问题在这里已有答案:
- Array.IsReadOnly inconsistent depending on interface implementation 4 answers
- Array.IsReadOnly不一致取决于接口实现4个答案
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>
.
我知道在.NET中,所有数组都派生自System.Array,System.Array类实现IList,ICollection和IEnumerable。实际数组类型还实现IList
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>
;.
这意味着如果你有一个String [],那么String []对象也是一个System.Collections.IList和一个System.Collections.Generic.IList
It's not hard to see why those IList's would be considered "ReadOnly", but surprisingly...
不难看出为什么那些IList会被认为是“ReadOnly”,但令人惊讶的是......
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.
在这两种情况下,尝试通过Remove()和RemoveAt()方法删除项会导致NotSupportedException。这表明两个表达式都对应于ReadOnly列表,但IList的ReadOnly属性不会返回预期值。
How come?
怎么来的?
2 个解决方案
#1
11
From MSDN:
来自MSDN:
Array implements the IsReadOnly property because it is required by the System.Collections.IList interface. An array that is read-only does not allow the addition, removal, or modification of elements after the array is created.
Array实现IsReadOnly属性,因为System.Collections.IList接口需要它。只读数组不允许在创建数组后添加,删除或修改元素。
If you require a read-only collection, use a System.Collections class that implements the System.Collections.IList interface.
如果需要只读集合,请使用实现System.Collections.IList接口的System.Collections类。
If you cast or convert an array to an IList interface object, the IList.IsReadOnly property returns false. However, if you cast or convert an array to a IList<T> interface, the IsReadOnly property returns true.
如果将数组转换或转换为IList接口对象,则IList.IsReadOnly属性将返回false。但是,如果将数组转换或转换为IList
接口,则IsReadOnly属性将返回true。
Read-only here means that the items in the array cannot be modified and that's why it returns false.
此处为只读意味着无法修改数组中的项,这就是它返回false的原因。
Also have a look at Array.IsReadOnly inconsistent depending on interface implementation.
另外看看Array.IsReadOnly不一致,具体取决于接口实现。
#2
11
This looks like a plain bug to me:
这看起来像一个普通的错误:
- It clearly isn't read-only, as the indexer allows it to be modified
- 它显然不是只读的,因为索引器允许它被修改
- It is not performing a conversion to any other kind of object
- 它没有执行到任何其他类型对象的转换
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:
ICollection
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.
虽然数组不允许添加或删除元素,但它显然允许修改。
#1
11
From MSDN:
来自MSDN:
Array implements the IsReadOnly property because it is required by the System.Collections.IList interface. An array that is read-only does not allow the addition, removal, or modification of elements after the array is created.
Array实现IsReadOnly属性,因为System.Collections.IList接口需要它。只读数组不允许在创建数组后添加,删除或修改元素。
If you require a read-only collection, use a System.Collections class that implements the System.Collections.IList interface.
如果需要只读集合,请使用实现System.Collections.IList接口的System.Collections类。
If you cast or convert an array to an IList interface object, the IList.IsReadOnly property returns false. However, if you cast or convert an array to a IList<T> interface, the IsReadOnly property returns true.
如果将数组转换或转换为IList接口对象,则IList.IsReadOnly属性将返回false。但是,如果将数组转换或转换为IList
接口,则IsReadOnly属性将返回true。
Read-only here means that the items in the array cannot be modified and that's why it returns false.
此处为只读意味着无法修改数组中的项,这就是它返回false的原因。
Also have a look at Array.IsReadOnly inconsistent depending on interface implementation.
另外看看Array.IsReadOnly不一致,具体取决于接口实现。
#2
11
This looks like a plain bug to me:
这看起来像一个普通的错误:
- It clearly isn't read-only, as the indexer allows it to be modified
- 它显然不是只读的,因为索引器允许它被修改
- It is not performing a conversion to any other kind of object
- 它没有执行到任何其他类型对象的转换
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:
ICollection
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.
虽然数组不允许添加或删除元素,但它显然允许修改。