Да, это случилось. В последней версии компилятора C# из состава Visual Studio “11” Beta изменилось правило разворачивания компилятором цикла foreach:

foreach (T x in xs) {
  f(x);
}

Цикл foreach - достаточно нетривиальная конструкция и имеет множество нюансов, я привожу лишь самый обычный случай, когда xs является переменной типа IEnumerable<T>. Раньше такой цикл компилировался прибилизительно следующим образом:

{
  IEnumerator<T> e = ((IEnumerable<T>) xs).GetEnumerator();
  try {
    T t;
    while (e.MoveNext()) {
      t = e.Current;
      f(t);
    }
  }
  finally {
    ((IDisposable)e).Dispose();
  }
}

Теперь компилируется вот так:

{
  IEnumerator<T> e = ((IEnumerable<T>) xs).GetEnumerator();
  try {
    while (e.MoveNext()) {
      T t = e.Current;
      f(t);
    }
  }
  finally {
    ((IDisposable)e).Dispose();
  }
}

То есть декларация переменной итерации уехала внутрь цикла while и это оказывает влияние на то, как теперь происходит замыкание на переменную итерации foreach. Так как замыкание в C# происходит по ссылке (замыкание на сами переменные, а не на их значения), то все анонимные методы и лямбда-выражения замыкаются на одну и ту же переменную и если их исполнение будет отложено за пределы цикла, то они “увидят” в переменной значение на момент последней итерации цикла, а не на момент создания анонимного метода/лямбда-выражения. Не смотря на то, что поведение чётко описано в спецификации и в некотором роде имеет право на существование, среднестатический юзер C# всё-же упёрто ожидает, что на каждой итерации цикла будет замыкаться на “fresh variable”. Ходят шутки, что изменение этого поведение убрало бы на StackOverflow добрую треть вопросов по C#.

Видимо, юзеры настолько задолбали C# team, что те решились на такой достаточно серьёзный breaking change. Однако факт остаётся фактом, теперь этот код:

using System;
using System.Collections.Generic;
using System.Linq;

static class Program {
  static void Main() {
    var xs = new List<Action>();
    foreach (var i in Enumerable.Range(1, 3)) {
      xs.Add(() => Console.WriteLine(i));
    }

    foreach (var action in xs) {
      action();
    }
  }
}

Выводит на экран ожидаемые:

1
2
3

Думаю, что решающим был тот факт, что сложно придумать пример, в котором предыдущее поведение было бы осмысленным в случае отложенного исполнения замыкания - в 99% случаях такие замыкания просто являются ошибками. Будем надеяться, что с таким изменением язык C# станет более логичным для пользователя, а скрытые ошибки, связанные с замыканием на переменную итерации foreach, сами пофиксятся, когда проекты будут собирать компилятором C# версии 5.0.

p.s. Эти изменения никак не затрагивают цикл for, в котором присутствует подобная проблема, так как цикл for на самом деле совсем не связан с переменными, которые могут определять (а могут и не определять) в части инициализации цикла.