gpt4 book ai didi

c# - 锁定可枚举可能会导致多重枚举吗?

转载 作者:行者123 更新时间:2023-11-30 16:10:22 24 4
gpt4 key购买 nike

我认为 ReSharper 在骗我。

我有这个扩展方法(希望)返回两个枚举的异或:

public static IEnumerable<T> Xor<T>(this IEnumerable<T> first, IEnumerable<T> second)
{
lock (first)
{
lock (second)
{
var firstAsList = first.ToList();
var secondAsList = second.ToList();

return firstAsList.Except(secondAsList).Union(secondAsList.Except(firstAsList));
}
}
}

ReSharper 认为我正在对两个参数执行 IEnumerable 的多重枚举,如您所见。如果我移除了锁,那么我就不会感到满意。

Multiple enumeration

ReSharper 是对还是错?我认为这是错误的。


编辑:我确实意识到我在多次枚举列表,但 ReSharper 说我在原始参数上多次枚举,我不知道'认为是真的。我将两个参数都枚举到一个列表中,这样我就可以执行实际的集合操作,但正如我所见,我实际上并没有迭代多次传递的参数。

例如,如果传递的参数实际上是查询结果,我相信此方法不会导致集合操作执行大量查询。我确实理解 ReSharper 警告多重枚举的含义:如果传递的枚举量生成量很大,那么如果它们被多次枚举,那么对它们执行多重枚举会慢得多。

此外,移除锁肯定会让 ReSharper 更快乐:

No multiple enumeration

最佳答案

您确实多次枚举了这两个列表。您没有多次枚举作为参数传递的可枚举。每次调用 Except 时,两个列表都会被枚举一次。对 Union 的调用不会再枚举任何一个序列,而是枚举对 Except 的两次调用的结果。

当然,在这样的上下文中多次迭代 List 并不是真正的问题;多次迭代不变的列表不会产生负面影响。

lock 语句与序列的枚举没有任何关系。锁定 IEnumerable 不会迭代它。当然,像这样锁定两个对象,特别是两个不受这部分代码范围限制的对象,非常是危险的。如果其他地方的代码(例如此方法的另一次调用)最终以相反的顺序锁定相同的对象,则很可能最终使用此庄园中使用的锁使程序陷入死锁。

关于c# - 锁定可枚举可能会导致多重枚举吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25938379/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com