使用 List<>在 foreach 循环中返回的 List.FindAll 与使用本地 List 有何不同?


这只是

为了知识,但我想知道使用包含List.FindAllforeach循环中返回的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不会多次呼叫FindAllFindAll只调用一次。

这记录在语言规范中(第 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变量是多余的,除了可读性原因。

最新更新