C# Foreach、扩展方法和IEnumerable
只是出于好奇问了个简单的问题。因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable。文档中还有一个警告,即在使用foreach循环时不能修改集合(我假设foreach循环在这方面不是非常线程安全的?) 文档: 另外,出于好奇,foreach循环在速度方面是否比for循环更优化?我知道foreach循环更容易键入/读取,但它执行速度是否比for循环快 查看MSDN文档中的列表,扩展方法Average由Enumerable定义。文档中说它对每个元素执行转换函数是什么意思? 这是否意味着扩展方法的行为类似于foreach循环? 文档: 假设我有两条线。假设我有一个由这两个线程共享的列表。第一个线程正在遍历此列表(foreach),第二个线程正在使用此列表上的平均扩展方法。那么这会导致抛出异常吗?我知道使用锁可以避免任何潜在的问题,但是为了便于讨论,让我们假设我没有使用锁 谢谢你抽出时间 因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable 否。任何支持C# Foreach、扩展方法和IEnumerable,c#,foreach,extension-methods,enumerable,C#,Foreach,Extension Methods,Enumerable,只是出于好奇问了个简单的问题。因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable。文档中还有一个警告,即在使用foreach循环时不能修改集合(我假设foreach循环在这方面不是非常线程安全的?) 文档: 另外,出于好奇,foreach循环在速度方面是否比for循环更优化?我知道foreach循环更容易键入/读取,但它执行速度是否比for循环快 查看MSDN文档中的列表,扩展方法Average由Enumerable定义。文档中说
GetEnumerator()
方法的对象,如果该方法反过来返回支持bool MoveNext()
方法和Current
属性的对象,则将支持foreach
IEnumerable
和IEnumerable
都支持这一点,因此实现它们的一切都将允许使用foreach
,但这不是唯一的方法。虽然这不仅是一种方便的方法,而且也是一种可以与采用IEnumerable
的方法(包括linq扩展方法)一起使用的方法,因此当您想要支持foreach
时,通常最好采用这种方法。(您可以选择也支持另一种方式,如列表
,但这几乎不值得)
另外,出于好奇,foreach循环在速度方面是否比for循环更优化
这很复杂,因为这是一个关于什么的问题,而不是关于什么的问题。for
具有优势是很常见的,因为它涉及的虚拟调用较少,但是当foreach
更快时,也有例外。如果您直接在数组上执行操作,那么foreach
会更慢,除非编译器实际捕获到这一点,并在幕后将其重写为For
,以便它们完全相同
文档中说它对每个元素执行转换函数是什么意思
这意味着Average
的特定重载将每个元素传递给传递给它的选择器的调用。此变换的结果才是平均值
这是否意味着扩展方法的行为类似于foreach循环
对。事实上,它们通常是每个人的foreach
。该特定方法是.NET Framework版本中的foreach
,以及.NET核心版本中的foreach
的轻微优化。在这两个版本中,有许多方法是foreach
。在一些已知性能更好的情况下,有些方法使用for
(参见上文关于有时是这种情况,有时不是这种情况的说明)。在绝大多数情况下,所做的许多优化都是不值得的,但是Linq方法被很多人大量使用,因此即使是一点点优化的努力也会得到回报
第一个线程正在遍历此列表(foreach),第二个线程正在使用此列表上的平均扩展方法。那么这会导致抛出异常吗
在这种特殊情况下,只要没有线程写入列表,这两个线程就不会相互造成任何问题。用于实现foreach
的对象在每个线程中分别创建,它们是唯一发生变化的对象。列表的文档不保证这一点,但不太可能更改
但这并不适用于所有支持foreach的foreach
。多线程foreach
没有任何承诺,除非给定的实现能够实现
因此,根据有关foreach循环的MSDN文档,它实现了System.Collections.IEnumerable
否。任何支持GetEnumerator()
方法的对象,如果该方法反过来返回支持bool MoveNext()
方法和Current
属性的对象,则将支持foreach
IEnumerable
和IEnumerable
都支持这一点,因此实现它们的一切都将允许使用foreach
,但这不是唯一的方法。虽然这不仅是一种方便的方法,而且也是一种可以与采用IEnumerable
的方法(包括linq扩展方法)一起使用的方法,因此当您想要支持foreach
时,通常最好采用这种方法。(您可以选择也支持另一种方式,如列表
,但这几乎不值得)
另外,出于好奇,foreach循环在速度方面是否比for循环更优化
这很复杂,因为这是一个关于什么的问题,而不是关于什么的问题。for
具有优势是很常见的,因为它涉及的虚拟调用较少,但是当foreach
更快时,也有例外。如果您直接在数组上执行操作,那么foreach
会更慢,除非编译器实际捕获到这一点