Давайте рассмотрим этот очень простой асинхронный метод:
static async Task myMethodAsync()
{
await Task.Delay(500);
}
Когда я компилирую это с помощью VS2013 (предварительный компилятор Roslyn), сгенерированная государственная машина является структурой.
private struct <myMethodAsync>d__0 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Когда я скомпилирую его с VS2015 (Roslyn), сгенерированный код таков:
private sealed class <myMethodAsync>d__1 : IAsyncStateMachine
{
...
void IAsyncStateMachine.MoveNext()
{
...
}
}
Как вы можете видеть, Roslyn генерирует класс (а не структуру). Если я правильно помню первые реализации поддержки async/await в старом компиляторе (CTP2012, я думаю), также сгенерировали классы, а затем он был изменен на структуру из соображений производительности. (в некоторых случаях вы можете полностью избежать бокса и распределения кучи...) (см. this)
Кто-нибудь знает, почему это было снова изменено в Roslyn? (У меня нет никаких проблем с этим, я знаю, что это изменение прозрачно и не меняет поведения какого-либо кода, мне просто интересно)
Edit:
Ответ от @Damien_The_Unbeliever (и исходного кода:)) imho объясняет все. Описанное поведение Roslyn применяется только для сборки отладки (и это необходимо из-за ограничения CLR, упомянутого в комментарии). В Release также генерирует структуру (со всеми преимуществами этого..). Таким образом, это, кажется, очень умное решение для поддержки как редактирования, так и продолжения и повышения производительности в производстве. Интересный материал, спасибо всем, кто участвовал!