C# 将泛型集合强制转换为列表一次,然后多次移除

C# 将泛型集合强制转换为列表一次,然后多次移除,c#,.net,casting,C#,.net,Casting,我有一个对象的通用集合作为对象的属性。这些数据来自sql查询和api。我想使用RemoveAt方法来高效地删除其中一些。但是VisualStudio向我抱怨RemoveAt方法未定义。我的直觉是将集合强制转换为列表,从而使我能够访问RemoveAt方法。我只想施放一次,然后根据需要多次使用RemoveAt。我可以使用Remove(object)命令,但它需要遍历集合来查找每个调用的对象,这比使用RemoveAt慢 以下是我正在尝试的: obj.stuckArray = obj.stuckArra

我有一个对象的通用集合作为对象的属性。这些数据来自sql查询和api。我想使用RemoveAt方法来高效地删除其中一些。但是VisualStudio向我抱怨RemoveAt方法未定义。我的直觉是将集合强制转换为列表,从而使我能够访问RemoveAt方法。我只想施放一次,然后根据需要多次使用RemoveAt。我可以使用Remove(object)命令,但它需要遍历集合来查找每个调用的对象,这比使用RemoveAt慢

以下是我正在尝试的:

obj.stuckArray = obj.stuckArray.ToList();
在这一行之后,我有一行代码如下所示:

obj.stuckArray.RemoveAt(1);
不幸的是,
RemoveAt
被加上红色下划线,Visual Studio发出的警告是:“ICollection不包含“RemoveAt”的定义”


是否可以一次强制转换并多次移除?或者这是不可能的?

只需使用三个语句而不是两个语句,使用局部变量:

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

这样一来,
stuckArray
的类型就不那么重要了:您只需要能够对其调用
ToList()
List
上的
RemoveAt
方法很好,因为这是
List

的类型。显然,您希望从数组中删除一个元素并将其存储回原始成员
stuckArray
。但是,由于
Icollection
没有定义方法
RemoveAt
,因此会出现错误。但是,该方法存在于
列表中

因此,请执行以下操作:

var tmp = obj.stuckArray.ToList();
tmp.RemoveAt(1);
obj.stuckArray = tmp;
但是,这将遍历整个集合,因为
ToList
会将整个集合复制到新集合中。但是我看不出有什么办法可以从数组中删除元素,因为数组没有
RemoveAt
-方法

根据您的编辑:为什么不在重新定义您的
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);

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

如果您可以控制暴露
struckArray
属性的对象,
您可以将
stuckArray
公开为
ICollection
,但在对象内部使用
列表作为其后台字段。然后,您可以添加一个方法,该方法根据项目的索引删除项目:

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);
     }
}
class-MyClass
{
私有列表_stuckArray;//当然,这不必是int。。。
公共ICollection StuckArray{get{return}\u StuckArray;}
public RemoveFromStuckArray(int索引)
{
_stuckArray.RemoveAt(索引);
}
}

这将使您能够保留对属性已有的任何引用,并且还提供了一种通过索引高效地删除项的方法,尽管我不确定首先从
ICollection
中通过索引删除项是否是一个好主意。

您不能更改成员的类型。改为定义类型为
List
的新属性。但是,如果
obj.stuckArray
已经是一个
ICollection
,它仍然应该工作,因为
List
实现了
ICollection
。因此,请说明如何定义
stuckArray
。只需创建一个类型为List的新变量,因此
List someList=obj.stuckArray.ToList()这两件事我都做过。不走运。这可能是一个代码感知问题。让我更新这个问题。您能将
ICollection stuckArray
更改为
IList stuckArray
?这样,您可以调用
RemoveAt()
和所有其他
IList
方法@Zoharpel你比我快。你可以编辑这个问题,即使它被否决或关闭。这就是为什么它被称为“暂停”的全部要点:使OP能够改进答案。当问题足够清楚时,可以重新打开并回答。为了澄清,我没有做这两件事。这在计算上似乎是不可取的。每次要删除元素时,我都必须将数组强制转换为列表。只使用“删除”会更快吗?我希望能够一次性将数组投射到列表中。@toshiomagic:我的答案是基于您已经尝试过的内容。我以为你想复印一份。(毕竟,在其他地方可能已经有对该集合的引用。)如果您想修改该集合,请更新您的问题以满足更多要求。(例如,类型必须是
ICollection
才能启动wit而不是
IList
)的任何原因?@toshiomagic:。您确定调用
ToList
会对您的整体性能产生如此大的影响吗?你量过这个了吗?
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);
     }
}