Fra*_*spo 2 c# arrays collections parameters readonly
我使用的是 Unity 版本 2023.1.6。我有一个继承自 的自定义集合Collection<T>。如果我实例化一个集合,然后尝试使用该.Add()方法,我会收到以下错误:
System.NotSupportedException: Collection is read-only.
at System.Collections.ObjectModel.Collection`1[T].Add (T item) [0x0000d] in <46a5f68c38604d68a85231bbf55f6b8f>:0
Run Code Online (Sandbox Code Playgroud)
我注意到仅当我使用此构造函数实例化集合时才会发生此错误:
public Selection(params T[] selectionElements) : base(selectionElements) { }
Run Code Online (Sandbox Code Playgroud)
我通过将构造函数更改为以下内容来修复错误:
public Selection(params T[] selectionElements) : base(selectionElements.ToList()) { }
Run Code Online (Sandbox Code Playgroud)
我不知道 LINQ 在幕后做了什么,甚至不知道为什么它有效(我刚刚尝试过......),所以我还有几个问题:
使用关键字有什么问题params?
是否params创建数组?如果是,为什么不能将数组作为 传递IList<T>?如果不行为什么没有编译时错误?
为什么 LINQ 方法修复了错误?
使用关键字没有问题params,问题是将数组作为 an 传递IList并期望能够添加到它。这是 C# 基类库未充分利用里氏替换原则(SOLID 中的“L”)的示例。
IList<T>包含“IsReadOnly”属性。一个Array<T>Implements IList<T>,但当然你不能添加到一个数组 - 你需要首先将所有内容复制到一个更大的数组中,这正是List<T>所做的工作。该IsReadOnly属性为true,如果您尝试调用Add()它将抛出异常。
IReadOnlyList<T>后来添加了一个单独的接口,以使发生的情况更加明显,但为了向后兼容,Array<T>仍然实现了原始接口。IList<T>
为什么当你打电话时会起作用selectionElements.ToList()?ToList()执行以下操作:
List<T>这意味着您现在拥有一个List<T>具有所有相同值的 a,它实现了IList<T>并且重要的是不是只读的
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |