The short answer is No, but the long answer has more to do with the way your code is written rather than the efficiency of the compiler.
In your first foreach loop, you obtain the source once, and iterate through its elements, effectively calling the method only once in order to obtain the source, but the nested foreach loop is called once for every iteration in the outer loop, and since the compiler has no way of knowing if the output of the method in the nested loop won't change, it actually makes sense for it to always call the method in order to obtain the source to iterate through.
In this case you need to improve your logic and avoid unnecessary calls to methods if you know the output will be the same, specially if you know that there is some resource consuming operation (such as a call to a DB) going on inside that method.
For the sake of giving a detailed answer, i tried your statements in the following program:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace StackOverflow
{
public class Class1
{
public static void Main(string[] args)
{
var serv1 = new Testserv1();
foreach (int x in serv1.CallA())
{
foreach (int y in serv1.CallB())
{
}
}
Console.WriteLine(string.Format("Calls to A: {0}", serv1.ACount));
Console.WriteLine(string.Format("Calls to B: {0}", serv1.BCount));
Console.ReadLine();
}
}
public class Testserv1
{
private static int CallACount = 0;
private static int CallBCount = 0;
public int ACount {
get
{
return CallACount;
}
}
public int BCount
{
get
{
return CallBCount;
}
}
public Testserv1()
{
//InitializeComponent();
}
public List<int> CallA()
{
CallACount++;
return new List<int>() {
1,2,3,4,5,6
};
}
public List<int> CallB()
{
CallBCount++;
return new List<int>() {
7,8,9,10,11,12
};
}
}
}
The output for the previous code is:
Calls to A: 1
Calls to B: 6