出于好奇,这只是一个简单的问题。因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable。在文档中还有一个警告,你在使用foreach循环时无法修改集合(我假设foreach循环在这方面不是非常安全的线程?)
文档:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in
另外,出于好奇,在速度方面,foreach循环比for循环更优化吗?我知道foreach循环更容易输入/读取,但它的执行速度比for循环更快吗?
查看MSDN文档以获取列表,扩展方法Average是由Enumerable定义的。当文档说它对每个元素执行转换函数时,文档意味着什么? 这是否意味着扩展方法的行为类似于foreach循环? 文档:https://msdn.microsoft.com/en-us/library/bb549067(v=vs.110).aspx
假设,假设我有两个主题。假设我有这两个线程共享的List。第一个线程遍历此列表(foreach),第二个线程使用此列表中的Average扩展方法。那么这会导致抛出异常吗?我知道使用锁可以避免任何潜在的问题,但为了讨论,我们假设我没有使用锁。
感谢您的时间。
答案 0 :(得分:2)
因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable
没有。支持GetEnumerator()
方法的任何内容都会返回支持bool MoveNext()
方法和Current
属性的对象,并支持foreach
。 IEnumerable
和IEnumerable<T>
都支持这一点,因此实现它们的所有内容都允许foreach
,但这不是唯一的方法。虽然这不仅是一种方便的方式,也是一种可以与IEnumerable<T>
包含linq扩展方法的方法一起使用的方法,所以当你想支持foreach
时,通常最好采用这种方法。 。 (您可以选择也支持List<T>
之类的其他方法,但它很少值得。)
另外,出于好奇,在速度方面,foreach循环比for循环更优化吗?
这很复杂,因为foreach
关于什么与for
的关系是for
。 foreach
通常具有优势,因为它涉及少量虚拟调用,但foreach
更快时会有例外情况。如果您直接在一个数组上执行操作会增加复杂性,那么for
会慢一些,除非编译器实际捕获它并在后面将它重写为Average
,因此它们完全相同。
当文档说它对每个元素执行转换函数时,文档意味着什么。
这意味着selector
的特定重载会将每个元素传递给传递给它的foreach
。这是转换的平均结果。
这是否意味着扩展方法的行为类似于foreach循环?
是。实际上,它们通常是foreach
。该特定方法是.NET Framework版本中的foreach
,并且在.NET Core版本中对foreach
进行了轻微优化。两个版本中的许多方法都是for
。有些方法在少数情况下使用foreach
,其中已知其性能更高(参见上文有关情况有时如何,有时则不然)。在绝大多数情况下,所做的大部分优化都不值得,但Linq方法被很多人大量使用,因此优化甚至一点点的努力都会得到回报。
第一个线程遍历此列表(foreach),第二个线程使用此列表中的Average扩展方法。那么这会导致抛出异常吗?
在这种特殊情况下,只要没有线程写入列表,两者就不会导致彼此出现任何问题。用于实现List<T>
的对象是在每个线程中单独创建的,它们是唯一的变异对象。 foreach
的文档无法保证这一点,但不太可能改变。
但这并不适用于支持foreach
的所有内容。除了给定的实现方式之外,多线程...
没有任何承诺。