foreach中内联运算和运算前计算的区别
Difference between inline operation and calculate before operation in foreach
我简单点(因为我在 Google 上没有找到任何东西,也许是因为我也不知道搜索什么)。
这有什么区别:
foreach(var x in g.GetList())
{
code
}
还有这个:
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
在性能方面还是在最佳实践方面,或者其他方面?
在下面的代码中,您直接调用了 foreach
中的 g.GetList()
方法
foreach(var x in g.GetList())
{
code
}
在下面的代码中,您在变量中分配了 g.GetList()
方法,然后您在 foreach 中调用该变量。与第一个代码相比,性能副,没有区别。只是编译器多编译了一行。就这些了。
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
但是如果 g.GetList();
方法 return 为空,您的第一个代码可能会引发空引用错误。所以最好的做法是在 foreach
中使用 variable/method 之前检查 null 条件
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
Performance is very important for clients, But Standard and understandable coding's are important for developers. I hope you can understand what is am explained.
这两段代码:
foreach(var x in g.GetList())
{
code
}
和
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
只有1个不同,那就是你自己把调用g.GetList()
的结果放到了一个变量中。
IL-wise,编译器输出的内容,当你编译为 RELEASE 模式时,将 100% 相同.
这是一个示例 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>();
}
将为 Method1 和 Method2 生成此 IL 代码:
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
所以除了你编写代码的方式之外没有区别。
我简单点(因为我在 Google 上没有找到任何东西,也许是因为我也不知道搜索什么)。
这有什么区别:
foreach(var x in g.GetList())
{
code
}
还有这个:
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
在性能方面还是在最佳实践方面,或者其他方面?
在下面的代码中,您直接调用了 foreach
中的g.GetList()
方法
foreach(var x in g.GetList())
{
code
}
在下面的代码中,您在变量中分配了 g.GetList()
方法,然后您在 foreach 中调用该变量。与第一个代码相比,性能副,没有区别。只是编译器多编译了一行。就这些了。
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
但是如果 g.GetList();
方法 return 为空,您的第一个代码可能会引发空引用错误。所以最好的做法是在 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
Performance is very important for clients, But Standard and understandable coding's are important for developers. I hope you can understand what is am explained.
这两段代码:
foreach(var x in g.GetList())
{
code
}
和
IEnumerable<object> list = g.GetList();
foreach(var x in list)
{
code
}
只有1个不同,那就是你自己把调用g.GetList()
的结果放到了一个变量中。
IL-wise,编译器输出的内容,当你编译为 RELEASE 模式时,将 100% 相同.
这是一个示例 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>();
}
将为 Method1 和 Method2 生成此 IL 代码:
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
所以除了你编写代码的方式之外没有区别。