与使用本地List相比,foreach循环中List.FindAll返回的List <>使用List <>的区别?

时间:2019-01-09 13:30:36

标签: c# linq

那只是为了知识,但我想知道使用包含List<>List.FindAll循环中返回的foreach的局部变量与直接调用{ ListFindAll循环中的{1}}吗?

此处的示例(foreach的类型为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会影响循环?

3 个答案:

答案 0 :(得分:1)

FindAll返回一个列表。这意味着在“某处”存在一个对象实例,因此,无论是否将该指针保存在变量中,都不应有所作为。 但是为了提高可读性和调试性,我建议将其放在此处。

答案 1 :(得分:1)

仅涉及一个线程,FindAll方法将仅被调用一次。

有关编译器如何处理foreach循环的更多信息,请参考this答案。

paletteResources变量是多余的,但出于可读性原因。

答案 2 :(得分:1)

这两种方法实际上是相同的。 foreach不会多次呼叫FindAllFindAll仅被调用一次。

这已在语言规范(第8.8.4节)中记录:

  

以上步骤如果成功,将明确产生一个集合   类型C,枚举器类型E和元素类型T。   表格

    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,以对其中的{{1} }对象。