将通用集合转换为List一次,然后将RemoveAt多次转换

时间:2018-01-30 16:52:36

标签: c# .net casting

我有一个通用的对象集合作为对象的属性。这些数据来自sql查询和api。我想使用RemoveAt方法有效地删除其中的一些。但是Visual Studio向我抱怨说RemoveAt方法是未定义的。我的直觉是将Collection转换为List,让我可以访问RemoveAt方法。我只想投一次,然后根据需要多次使用RemoveAt。我可以使用Remove(object)命令,但它需要遍历Collection以查找每次调用的对象,这比使用RemoveAt

要慢。

以下是我的尝试:

obj.stuckArray = obj.stuckArray.ToList();

在这一行之后,我有一行代码如下:

obj.stuckArray.RemoveAt(1);

不幸的是,RemoveAt带有红色下划线,而Visual Studio的警告显示:" ICollection不包含' RemoveAt'"

的定义

是否可以施放一次并删除多次?或者这不可能吗?

3 个答案:

答案 0 :(得分:2)

使用局部变量

在三个语句而不是两个语句中执行此操作
var list = obj.stuckArray.ToList();
list.RemoveAt(1);
obj.stuckArray = list;

这样stuckArray的类型无关紧要:您只需要能够在其上调用ToList()RemoveAt上的List<T>方法很好,因为这是list的类型。

答案 1 :(得分:1)

显然,您希望从数组中删除元素并将其存储回原始成员stuckArray。但是,由于Icollection没有定义方法RemoveAt,因此您会收到错误消息。然而,该方法存在于List<T>上。

所以请改为:

var tmp = obj.stuckArray.ToList();
tmp.RemoveAt(1);
obj.stuckArray = tmp;

然而,无论如何,这将遍历整个集合,因为ToList会将整个集合复制到一个新集合中。但是我没有看到任何方法来删除数组中的元素,因为数组没有RemoveAt - 方法。

根据您的编辑:为什么不在重新定义Remove之后制作stuckArray

var tmp = obj.stuckArray.ToList();
obj.stuckArray = tmp;

现在您可以根据需要随时拨打RemoveAt

((List<MyType>)obj.stuckArray).RemoveAt(1);
((List<MyType>)obj.stuckArray).RemoveAt(1);
((List<MyType>)obj.stuckArray).RemoveAt(1);

投放这么多次不会对您的表现产生重大影响,因为obj.stuckArray已经 List<MyType>。另一方面,RemoveAt会产生效果,因为该方法将复制内部数组,如source-code for RemoveAt所示:

public void RemoveAt(int index) {
    if ((uint)index >= (uint)_size) {
        ThrowHelper.ThrowArgumentOutOfRangeException();
    }
    Contract.EndContractBlock();
    _size--;
    if (index < _size) {
        Array.Copy(_items, index + 1, _items, index, _size - index); // here the entire array will be traversed again
    }
    _items[_size] = default(T);
    _version++;
}

因此,通过调用RemoveAt三次,您还可以复制内部数组三次。

答案 2 :(得分:0)

如果您可以控制公开struckArray属性的对象,则 您可以将stuckArray公开为ICollection<T>,但在对象内部使用List<T>作为其支持字段。然后,您可以添加一个方法来删除项目的索引:

class MyClass
{
     private list<int> _stuckArray; // of course, this doesn't have to be int...

     public ICollection<int> StuckArray {get {return _stuckArray;}}

     public RemoveFromStuckArray(int index)
     {
          _stuckArray.RemoveAt(index);
     }
}

这将使您能够保留您已经拥有的任何参考资产,并提供一种方法来有效地删除其索引项目,但我不确定启用这样的好主意首先从ICollection按索引删除项目。