I'm not the best at reading MSIL, but I did some testing and it seems to agree with what everyone is saying: the collection is only retrieved one time. See below for the MSIL if you're curious.
public static void ATest() {
foreach (string s in GetSomeStrings()) {
Console.WriteLine(s);
}
}
public static void BTest() {
string[] strings = GetSomeStrings();
foreach (string s in strings) {
Console.WriteLine(s);
}
}
public static string[] GetSomeStrings() {
return new string[] {
"string1", "string2", "string3"
};
}
ATest() MSIL:
.method public hidebysig static void ATest() cil managed
{
.maxstack 2
.locals init (
[0] string s,
[1] string[] CS$6$0000,
[2] int32 CS$7$0001,
[3] bool CS$4$0002)
L_0000: nop
L_0001: nop
--->L_0002: call string[] EdProgAppData_BLL.Common::GetSomeStrings()
L_0007: stloc.1
L_0008: ldc.i4.0
L_0009: stloc.2
L_000a: br.s L_001d
L_000c: ldloc.1
L_000d: ldloc.2
L_000e: ldelem.ref
L_000f: stloc.0
L_0010: nop
L_0011: ldloc.0
L_0012: call void [mscorlib]System.Console::WriteLine(string)
L_0017: nop
L_0018: nop
L_0019: ldloc.2
L_001a: ldc.i4.1
L_001b: add
L_001c: stloc.2
L_001d: ldloc.2
L_001e: ldloc.1
L_001f: ldlen
L_0020: conv.i4
L_0021: clt
L_0023: stloc.3
L_0024: ldloc.3
L_0025: brtrue.s L_000c
L_0027: ret
}
BTest() MSIL:
.method public hidebysig static void BTest() cil managed
{
.maxstack 2
.locals init (
[0] string[] strings,
[1] string s,
[2] string[] CS$6$0000,
[3] int32 CS$7$0001,
[4] bool CS$4$0002)
L_0000: nop
--->L_0001: call string[] EdProgAppData_BLL.Common::GetSomeStrings()
L_0006: stloc.0
L_0007: nop
L_0008: ldloc.0
L_0009: stloc.2
L_000a: ldc.i4.0
L_000b: stloc.3
L_000c: br.s L_001f
L_000e: ldloc.2
L_000f: ldloc.3
L_0010: ldelem.ref
L_0011: stloc.1
L_0012: nop
L_0013: ldloc.1
L_0014: call void [mscorlib]System.Console::WriteLine(string)
L_0019: nop
L_001a: nop
L_001b: ldloc.3
L_001c: ldc.i4.1
L_001d: add
L_001e: stloc.3
L_001f: ldloc.3
L_0020: ldloc.2
L_0021: ldlen
L_0022: conv.i4
L_0023: clt
L_0025: stloc.s CS$4$0002
L_0027: ldloc.s CS$4$0002
L_0029: brtrue.s L_000e
L_002b: ret
}