为了知识,但我想知道使用包含List.FindAll
在foreach
循环中返回的List<>
的局部变量与在foreach
循环内直接ListFindAll
调用之间是否存在显着差异?
这里的例子(m_Project.Resources
类型List<Resources.ResourceBase>
):
List<Resources.ResourceBase> paletteResources = m_Project.Resources.FindAll(r => r.GetType() == typeof(Resources.PaletteResource));
foreach(Resources.ResourceBase resource in paletteResources)
对
foreach(Resources.ResourceBase resource in m_Project.Resources.FindAll(r => r.GetType() == typeof(Resources.PaletteResource)))
除了可读性之外,我想知道使用第二种方法是否有与线程相关的问题的性能?就像 foreach
循环会多次调用List.FindAll
,或者如果通过修改另一个线程中的 List 会影响循环?
这两种方法实际上是相同的。 foreach
不会多次呼叫FindAll
。 FindAll
只调用一次。
这记录在语言规范中(第 8.8.4 节):
上述步骤如果成功,则明确生成集合 类型 C、枚举器 E 型和元素类型 T。一个 foreach 语句 形式
foreach (V v in x) embedded-statement
然后扩展到:
E e = ((C)(x)).GetEnumerator();
try {
while (e.MoveNext()) {
V v = (V)(T)e.Current;
embedded-statement
}
}
finally {
// Dispose e
}
在您的情况下,x
将被替换为m_Project.Resources.FindAll(r => r.GetType() == typeof(Resources.PaletteResource))
E e = ((C)(m_Project.Resources.FindAll(r => r.GetType() == typeof(Resources.PaletteResource)))).GetEnumerator();
try {
while (e.MoveNext()) {
如您所见,FindAll
只调用一次。
我想,两者之间的唯一区别是,如果您使用第一个,则留下一个局部变量paletteResources
,您可能会意外使用它来改变一些Resources.ResourceBase
对象。
FindAll 返回一个列表。这意味着"某处"有一个对象实例,所以无论您是否将该指针保存在变量中,它都应该没有区别。但是为了可读性和调试,我建议把它放在那里。
只涉及一个线程,FindAll
方法只会调用一次。
有关编译器如何处理foreach
循环的更多信息,请参阅此答案。
paletteResources
变量是多余的,除了可读性原因。