Средство отладки Visual Studio "быстрый просмотр" и лямбда-выражения


Почему я не могу использовать лямбда-выражения при отладке в окне "быстрый просмотр"?

UPD: Смотрите также

http://blogs.msdn.com/b/jaredpar/archive/2009/08/26/why-no-linq-in-debugger-windows.aspx

http://blogs.msdn.com/b/jaredpar/archive/2010/06/02/why-is-linq-absent-from-debugger-windows-part-2.aspx

9 93

9 ответов:

лямбда-выражения, как и анонимные методы, на самом деле очень сложные звери. Даже если мы исключим Expression (.NET 3.5), что все еще оставляет много сложности, не в последнюю очередь захваченные переменные, которые принципиально перестраивают код, который их использует (то, что вы думаете о переменных, становится полями в классах, созданных компилятором), с небольшим количеством дыма и зеркал.

как таковой, я нисколько не удивлен, что вы не можете использовать их лениво - есть много работы компилятора (и генерации типов за кулисами), которая поддерживает эту магию.

нет вы не можете использовать лямбда-выражения в окне watch / locals / immediate. Как отметил Марк, это невероятно сложно. Я хотел бы погрузиться немного дальше в эту тему, хотя.

что большинство людей не рассматривают с выполнением анонимной функции в отладчике, так это то, что она не происходит в вакууме. Сам акт определения и запуска анонимной функции изменяет базовую структуру базы кода. Изменение кода, в общем-то, и в в частности, из непосредственного окна, это очень сложная задача.

рассмотрим следующий код.

void Example() {
  var v1 = 42;
  var v2 = 56; 
  Func<int> func1 = () => v1;
  System.Diagnostics.Debugger.Break();
  var v3 = v1 + v2;
}

этот конкретный код создает одно закрытие для захвата значения v1. Захват закрытия требуется всякий раз, когда анонимная функция использует переменную, объявленную вне ее области. Для всех целей и задач v1 больше не существует в этой функции. Последняя строка на самом деле выглядит следующим образом

var v3 = closure1.v1 + v2;

если пример функции выполняется в отладчик остановится на линии разрыва. Теперь представьте, что пользователь ввел следующее в окно просмотра

(Func<int>)(() => v2);

чтобы правильно выполнить это, отладчик (или более подходящий EE) должен был бы создать закрытие для переменной v2. Это трудно, но не невозможно сделать.

что действительно делает эту трудную работу для EE, хотя это последняя строка. Как теперь должна выполняться эта строка? Для всех намерений и целей анонимная функция удалена переменная v2 и заменил его на closure2.v2. Так что последняя строка кода действительно теперь должна читать

var v3 = closure1.v1 + closure2.v2;

тем не менее, чтобы фактически получить этот эффект в коде, требуется, чтобы EE изменил последнюю строку кода, которая на самом деле является действием ENC. Хотя этот конкретный пример возможен, большая часть сценариев-нет.

что еще хуже, выполнение этого лямбда-выражения не должно создавать новое закрытие. На самом деле это должно быть добавление данных к оригиналу закрытие. На этом этапе вы запускаете прямо в ограничения ENC.

мой маленький пример, к сожалению, только малая часть проблем, с которыми мы столкнулись. Я говорю, я напишу полный пост в блоге на эту тему и, надеюсь, у меня будет время в эти выходные.

вы не можете использовать лямбда-выражения в непосредственных или наблюдательных окнах.

однако, вы можете использовать система.В LINQ.Динамические выражения, которые принимают форму .Где ("Id = @0", 2) - он не имеет полного спектра методов, доступных в стандартном Linq, и не имеет полной мощности лямбда-выражений, но все же это лучше, чем ничего!

будущее пришло!

добавлена поддержка отладки лямбда-выражений в Visual Studio 2015 (предварительный просмотр на момент написания).

вычислитель выражений пришлось переписать, поэтому многие функции отсутствуют: удаленная отладка ASP.NET, объявляя переменные в непосредственном окне, проверяя динамические переменные и т. д. Также в настоящее время не поддерживаются лямбда-выражения, требующие вызовов собственных функций.

Это может помочь: Расширенный открывшееся окно в Visual студии (использовать LINQ, лямбда-выражения expr в отладки)

всего наилучшего, Патрик

лямбда-выражения не поддерживаются выражения отладчика... что неудивительно, поскольку во время компиляции они используются для создания методов (или деревьев выражений), а не выражений (посмотрите в отражателе с переключением дисплея на .NET 2, чтобы увидеть их).

плюс, конечно, они могут образовать закрытие, еще один целый слой структуры.

в VS 2015 Вы можете сделать это сейчас,это одна из новых функций добавили они.

Если вам все еще нужно использовать Visual Studio 2013, Вы можете написать цикл или лямбда-выражение в непосредственном окне, используя также окно консоли диспетчера пакетов. В моем случае, я добавил список в верхней части функции:

private void RemoveRoleHierarchy()
{
    #if DEBUG
    var departments = _unitOfWork.DepartmentRepository.GetAll().ToList();
    var roleHierarchies = _unitOfWork.RoleHierarchyRepository.GetAll().ToList();
    #endif

    try
    {
        //RoleHierarchy
        foreach (SchoolBo.RoleHierarchy item in _listSoRoleHierarchy.Where(r => r.BusinessKeyMatched == false))
            _unitOfWork.RoleHierarchyRepository.Remove(item.Id);

        _unitOfWork.Save();
    }
    catch (Exception e)
    {
        Debug.WriteLine(e.ToString());
        throw;
    }
}

где мой

чтобы ответить на ваш вопрос, вот официальное объяснение Visual Studio Program Manager, почему вы не можете этого сделать. Короче говоря, потому, что "это очень сложно" реализовать в против. Но эта функция в настоящее время (как обновлялась августа 2014 года).

разрешить оценку лямбда-выражений при отладке

Добавить свой голос, пока вы там!