Это просто не реализовано как оптимизация или мне чего-то не хватает?
В приведенном вами примере вы, вероятно, не захотите выполнять такое преобразование кода, поскольку оно меняет семантику программы. Если new
выдает исключение, в исходной программе это должно быть сделано до выполнения делегата, а при преобразовании побочный эффект откладывается. Независимо от того, что это важное свойство, которое должно быть сохранено спорно. (И это также создает проблемы для отладчика; отладчик уже должен делать вид, что элементы классов замыкания являются локальными для тела, содержащего метод, и эта оптимизация может еще больше усложнить это.)
Тем не менее, более общий смысл уместен. Существует множество оптимизаций, которые вы можете выполнить, если знаете, что закрытая переменная используется только для ее значения.
Когда я был в команде компиляторов - я ушел в 2012 году - Нил Гафтер и я рассмотрел возможность реализации таких оптимизаций, а также ряд более сложных оптимизаций, предназначенных для уменьшения вероятности слишком долгого продления срока службы дорогого объекта. случайно.
В сторону: Самый простой из более сложных сценариев: у нас есть две лямбды, преобразованные в делегатов; один хранится в недолговечной переменной и закрывается над локальной переменной, содержащей ссылку на дорогой объект; один хранится в долгоживущей переменной и закрывается над локальной переменной, которая ссылается на дешевый объект. Дорогой объект живет столько же, сколько долгоживущая переменная, даже если он не используется. В более общем смысле, множественные замыкания могут быть построены как раздел на основе закрытого отношения; в то время мы только разделяли замыкания на основе вложенности; замыкания на том же уровне вложенности были одним замыканием. Данный сценарий встречается редко и есть очевидные обходные пути, но было бы неплохо, если бы его вообще не было.
Мы не сделали этого, потому что в течение периода, когда мы внедряли Roslyn, были более важные оптимизации и функции, и мы не хотели добавлять риск к уже длинному графику.
Мы могли бы выполнять такие оптимизации уверенно, потому что в C # довольно легко узнать, когда локальный псевдоним был добавлен, и поэтому вы можете точно знать, записывается ли он когда-либо после создания замыкания.
Я не знаю, были ли эти оптимизации реализованы за это время; скорее всего нет.
Я также не знаю, выполняет ли компилятор такие оптимизации для локальных функций C # 7, хотя я подозреваю, что ответ "да". Посмотрите, что произойдет, если вы попробуете локальную функцию!