De depuración de Visual Studio “inspección rápida” de la herramienta y de las expresiones lambda

¿Por qué no puedo utilizar expresiones lambda, mientras que la depuración en Rápida “de la ventana” observación?

UPD: véase también

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

Este ha sido completado y está disponible en el VS de 2015 vista previa. visualstudio.uservoice.com/forums/121579-visual-studio/…
gigi.nullneuron.net/gigilabs/…
he intentado ejemplo muy sencillo dado en MSDN para la expresión lambda, pero no funciona. me han VS 2015 enterprise edition
para habilitar la lambda de apoyo en la depuración, “el Uso de Administrado el Modo de Compatibilidad” tiene que ser marcada (stackoverflow.com/a/36559817/818321) Como resultado, usted no será capaz de utilizar los puntos de interrupción condicionales: blogs.msdn.microsoft.com/devops/2013/10/16/… y stackoverflow.com/a/35983978/818321

OriginalEl autor lak-b | 2009-04-07

9 respuestas

  1. 63

    Las expresiones Lambda, como los métodos anónimos, son realmente muy complejo bestias. Incluso si descartamos Expression (.NET 3.5), que deja a un mucho de la complejidad, de no menos de ser capturado variables, que en lo fundamental a re-estructurar el código que utiliza (lo que usted piensa de como variables convertido en campos generado por el compilador clases), con un poco de humo y espejos.

    Como tal, no estoy en el menos sorprendido de que no se pueden utilizar de brazos cruzados – no es un mucho de compilador de trabajo (y el tipo de generación de detrás de las escenas) que apoya esta magia.

    OriginalEl autor Marc Gravell

  2. 90

    No, usted no puede utilizar las expresiones lambda en el reloj /locales /ventana inmediato. Como Marc ha señalado que esto es increíblemente complejo. Yo quería profundizar un poco más en el tema, aunque.

    Lo que la mayoría de las personas no consideran que con la ejecución de una función anónima en el depurador es que no se produce en un vaccuum. El acto mismo de la definición y ejecución de una función anónima cambios en la estructura subyacente de la base de código. Cambiar el código, en general, y en particular desde la ventana inmediato, es una tarea muy difícil.

    Considere el siguiente código.

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

    Este código crea un cierre para capturar el valor de v1. Cierre de captura se requiere cada vez una función anónima se utiliza una variable declarada fuera de su alcance. Para todos los intentos y propósitos de la v1 ya no existe en esta función. La última línea en realidad se parece más a la siguiente

    var v3 = closure1.v1 + v2;

    Si el Ejemplo de la función se ejecuta en el depurador se detendrá en el Salto de línea. Ahora, imagínese si el usuario escribió lo siguiente en la ventana de inspección

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

    Con el fin de ejecutar correctamente esta el depurador (o más adecuadas a la EE) necesita para crear un cierre para la variable v2. Esto es difícil, pero no imposible de hacer.

    Lo que realmente hace de este un trabajo difícil para los EE pesar de que es la última línea. ¿Cómo se debe que la línea de ser ejecutado? Para todos los intentos y propósitos de la función anónima eliminado la variable v2 y lo reemplazó con closure2.v2. Así que la última línea de código que ahora realmente necesita leer

    var v3 = closure1.v1 + closure2.v2;

    Sin embargo, para realmente obtener este efecto en el código requiere que el EE para cambiar la última línea de código que en realidad es una ENC acción. A pesar de que este ejemplo es posible, una buena parte de los escenarios no son.

    Lo peor de todo es que la ejecución de expresión lambda no debería ser la creación de un nuevo cierre. Realmente se debe anexar datos a la original de cierre. En este punto se ejecuta directamente en las limitaciones ENC.

    Mi pequeño ejemplo desafortunadamente sólo roza la superficie de los problemas que nos encontramos. Yo sigo diciendo que voy a escribir un blog completo sobre este tema y espero tener tiempo este fin de semana.

    +1 para el detalle… voy a mirar hacia fuera para la entrada de blog ;-p
    Se quejan, se quejan, aceptar la mediocridad, gemir, gemir. El depurador es el corazón de la IDE, y se rompió! Las Lambdas en la ventana de inspección no es necesario capturar cualquier cosa. Como cualquier otro reloj de código, que sólo tienen sentido en el marco de pila. (O bien la captura de la variable, mover a otra función con el mismo nombre de variable… ¿y qué?) El depurador se entiende que rompiera el compilador. Hacer que funcione!
    Por qué simples no permiten capturar las variables en las lambdas en la ventana de inspección. Simple y podría permitir que un montón de depuración de los escenarios donde las lambdas sólo están siendo utilizados en verdad código funcional.
    incluso que es todavía un enorme en tomar. Se requiere de la EE para generar la función completa del cuerpo de la llamada de vuelta (todo el camino a la IL). El EE no hace nada de este tipo hoy en día, en cambio, es un intérprete.
    se puede compartir post en el blog de marc hablando

    OriginalEl autor JaredPar

  3. 49

    Usted no puede utilizar expresiones lambda en el Inmediato o el Reloj de windows.

    Sin embargo, puede utilizar Sistema.Linq.Expresiones dinámicas, que toman la forma .Donde(“Id = @0”, 2) – no tiene la gama completa de métodos disponibles en el estándar de Linq, y no tiene toda la potencia de las expresiones lambda, pero aún así, es mejor que nada!

    Bueno … mientras los demás explicó mientras no era posible, esta al menos nos ofrece una posible solución. +1
    Solo para aclarar, “Sistema de Importación.Linq.Dinámica” y, a continuación, en la ventana de depuración que escribir ‘”Donde(algo así.AsQueryable,”propiedad>xyz”,nada)’
    Esto es genial. A pesar de no obtener la gama completa de métodos de Extensión de Linq, por ejemplo, no hay .Any(string predicate), que poner algo como: .Where("Id>2").Any() en la Ventana de inspección, o el Pin de la Fuente. Es genial!

    OriginalEl autor stusherwin

  4. 20

    El futuro ha llegado!

    Apoyo para la depuración de las expresiones lambda ha sido añadido a Visual Studio 2015 (Vista previa en el momento de la escritura).

    Evaluador de expresiones tuvo que ser reescrito, por lo que muchas de las características que faltan: la depuración remota ASP.NET, la declaración de variables en la ventana Inmediato, la inspección de la dinámica de las variables, etc. También las expresiones lambda que requieren las llamadas a funciones nativas no son compatibles actualmente.

    OriginalEl autor Athari

  5. 2

    Expresiones Lambda no son compatibles con el depurador del evaluador de expresiones… lo cual no es sorprendente, ya que en tiempo de compilación que se utilizan para crear métodos (o Árboles de Expresión) en lugar de las expresiones (echa un vistazo en el Reflector con la pantalla de seleccionar .NET 2 para verlos).

    Además, por supuesto, podrían formar un cierre, otra capa entera de la estructura.

    Bueno, que que crear métodos, pueden crear Expression árboles – depende del contexto.
    Por supuesto, se expandió.

    OriginalEl autor Richard

  6. 1

    En el VS de 2015, puede hacerlo ahora,esta es una de las nuevas características que agregan.

    OriginalEl autor loneshark99

  7. 1

    Si usted todavía tiene que usar Visual Studio 2013, en realidad se puede escribir un bucle, o expresión lambda en la ventana inmediato haciendo también uso de la consola del administrador de paquetes de la ventana. En mi caso, he añadido una lista en la parte superior de la función:

    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;
        }
    }

    Donde mi GetAll() función es:

    private DbSet<T> _dbSet;
    
    public virtual IList<T> GetAll()
    {
        List<T> list;
        IQueryable<T> dbQuery = _dbSet;
        list = dbQuery
            .ToList<T>();
    
        return list;
    }

    Aquí yo seguía recibiendo el siguiente error, así que quería imprimir todos los elementos en los distintos repositorios:

    InnerException {“La instrucción DELETE en conflicto con la REFERENCIA de la restricción de la \”FK_dbo.Department_dbo.RoleHierarchy_OranizationalRoleId\”. El conflicto se produjo en la base de datos \”CC_Portal_SchoolObjectModel\”, tabla \”dbo.Departamento\”, la columna ‘OranizationalRoleId’.\r\nel instrucción se ha terminado.”} Sistema.Exception {Sistema.De datos.SqlClient.SqlException}

    Entonces, puedo averiguar cuántos registros se encuentran en el departamento del repositorio mediante la ejecución de este en la ventana inmediato:

    _unitOfWork.DepartmentRepository.GetAll().ToList().Count

    Que regresó 243.

    Por lo tanto, si usted ejecute lo siguiente en la consola del administrador de paquetes, imprime todos los elementos:

    PM> for($i = 0; $i -lt 243; $i++) { $a = $dte.Debugger.GetExpression("departments[$i].OrgagnizationalRoleId"); Write-Host $a.Value $i }

    El autor de la idea se puede encontrar aquí

    OriginalEl autor user8128167

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *