在c#中,扩展正在用foreach遍历的List是安全的吗?

本文关键字:List 安全 遍历 foreach 扩展 | 更新日期: 2023-09-27 18:16:26

在c#中扩展foreach遍历的List是安全的吗?

在c#中,扩展正在用foreach遍历的List是安全的吗?

我假定您所说的扩展是指向集合中添加新项。如果是,那么答案是否定的,您将在遍历中得到一个异常。我不相信任何集合能做到这一点。

你可以创建一个新的列表,然后在原来的列表上做一个adrange

在c#中,扩展一个正在被foreach遍历的List是否安全?如果不是,那么其他系列呢?

很少有集合可以在迭代时安全地添加。这里有很多选项——最常见的是从原始集合构建一个新集合,或者在迭代时将项目添加到临时集合中,然后在最后将它们全部添加到原始集合中。

框架中唯一考虑迭代和插入的集合是一些并发集合。例如,您可以通过GetConsumingEnumerable迭代BlockingCollection<T>,并同时向其添加项。然而,这是为了一个不同的目的——它通常用于有一个单独的消费者和生产者线程,一个添加,而另一个处理项目。因此,在它自己的循环中这样做将是一个非常奇怪的用例。

不,您将得到一个异常。虽然不建议这样做,但您可以通过使用一个简单的for循环来实现您所要寻找的功能。你得到异常的原因是foreach的工作方式。当编译时,它实际上是使用IEnumerable<T>IEnumerable,由List<T>实现来获取项目。现在您可以创建自己的集合,这将允许类似的内容,但同样,不推荐。

foreach仅用于查看任何集合的值,如果您要更改集合中的元素数量-将抛出异常。如果您要更改集合中的值-什么也不会发生,但微软建议不要在这种情况下使用foreach。如果您需要更改元素或元素数量,请使用list.ToArray()和FOR循环遍历数组。

新建一个列表。例如使用按钮:

List<Button> list = new List<Button>();
list.Add(new Button());
list.Add(new Button());
foreach (Button button in new List<Button>(list))
    list.Add(new Button());

不是最好的解决方案,但可能是最简单的。

这里有些可能是好的,有些复杂的解决方案。基于列表的长度和当前位置循环遍历列表怎么样?

UInt16 n = 0;
while (n < list.Count)
{
    ... // might add new elements to the end of the list
    n++;
}