代码之家  ›  专栏  ›  技术社区  ›  Im Flash

foreach中内联运算和运算前计算之间的差异

  •  -1
  • Im Flash  · 技术社区  · 8 年前

    我很简单(因为我没有在谷歌上找到任何东西,可能是因为我也不知道搜索什么)。

    foreach(var x in g.GetList())
    {
     code
    }
    

    这是:

    IEnumerable<object> list = g.GetList();
    foreach(var x in list)
    {
     code
    }
    

    在性能或最佳实践方面,还是其他方面?

    2 回复  |  直到 8 年前
        1
  •  0
  •   Lasse V. Karlsen    8 年前

    这两段代码:

    foreach(var x in g.GetList())
    {
     code
    }
    

    IEnumerable<object> list = g.GetList();
    foreach(var x in list)
    {
     code
    }
    

    只有一个区别,那就是您放置了调用的结果 g.GetList() 你自己变成一个变量。

    IL-wise,当您为发布模式编译时,编译器输出的内容将是 完全相同 .

    这是一个样本 LINQPad 计划:

    void Main() {  }
    
    static void Method1()
    {
        foreach (var x in g.GetList()) { }
    }
    
    static void Method2()
    {
        IEnumerable<object> list = g.GetList();
        foreach (var x in list) { }
    }
    
    static class g
    {
        public static IEnumerable<object> GetList() => new List<object>();
    }
    

    将为生成此IL代码 二者都 方法1和方法2:

    IL_0000:  call        UserQuery+g.GetList
    IL_0005:  callvirt    System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator
    IL_000A:  stloc.0     
    IL_000B:  br.s        IL_0014
    IL_000D:  ldloc.0     
    IL_000E:  callvirt    System.Collections.Generic.IEnumerator<System.Object>.get_Current
    IL_0013:  pop         
    IL_0014:  ldloc.0     
    IL_0015:  callvirt    System.Collections.IEnumerator.MoveNext
    IL_001A:  brtrue.s    IL_000D
    IL_001C:  leave.s     IL_0028
    IL_001E:  ldloc.0     
    IL_001F:  brfalse.s   IL_0027
    IL_0021:  ldloc.0     
    IL_0022:  callvirt    System.IDisposable.Dispose
    IL_0027:  endfinally  
    IL_0028:  ret
    

    因此,除了如何编写代码之外,没有什么不同。

        2
  •  -1
  •   Ramesh Rajendran    8 年前

    在下面的代码中,您直接调用 g.GetList() foreach中的方法

    foreach(var x in g.GetList())
    {
     code
    }
    

    在下面的代码中,您被分配了 g、 GetList() 方法,然后在foreach中调用该变量。与第一个代码相比,性能相差不大。只需编译器编译额外的一行。这就是全部。

    IEnumerable<object> list = g.GetList();
    foreach(var x in list)
    {
     code
    }
    

    但是您的第一个代码可能会抛出空引用错误,如果 g.GetList(); 方法返回null。因此,最佳做法是在foreach中使用变量/方法之前检查空条件

    IEnumerable<object> list = g.GetList();
    if(list == null)
    {
    retur false;
    }
    foreach(var x in list)
    {
     code
    }
    

    并且必须使用真实对象,而不是使用对象和动态数据类型,因为 type safe .

    IEnumerable<Employee> list = g.GetList();// as per employee is your class name
    

    性能对客户来说非常重要, 但是标准和可理解的编码对开发人员来说很重要 . 我希望你能理解我的解释。