11

tengo un método que devuelve un IEnumerable<> el que se acumula el uso de la sintaxis yield return:problema con el reloj de depuración en Visual Studio con métodos empadronador retorno rendimiento

namespace Validation 
{ 
    public class UserValidator 
    { 
     public IEnumerable<ValidationError> Validate(User user) 
     { 
      if (String.IsNullOrEmpty(user.Name)) 
      { 
       yield return new ValidationError("Name", ValidationErrorType.Required); 
      } 

      [...] 

      yield break; 
     } 
    } 
} 

Si pongo un punto de interrupción en el método, que pueda paso a paso por cada línea, pero si trato de usar el reloj o ventanas inmediatas para ver el valor de una variable consigo este error:

Cannot access a non-static member of outer type 'Validation.UserValidator.Validate' via nested type 'Validation.UserValidator'

¿alguien sabe por qué es y cómo puedo conseguir alrededor de él?

Respuesta

7

OK, acabo de probarlo y veo lo que quieres decir. ¡Eso es doloroso! Sospecho que tiene que ver con el trabajo entre bastidores que hace el compilador (creando clases anidadas y demás) para implementar la lógica de tipo de máquina de estado reanudable para yield. Una forma de evitarlo (la forma en que probé originalmente su código) es hacer que el método Validate sea estático, aunque obviamente eso no es bueno para el diseño.

Creo que la razón del mensaje de error es tan obtuso es una combinación de:

  1. Las clases generadas no existen en su fuente, por lo que VS no tiene nombres por los que se refieren a ellos.
  2. IIRC, los nombres generados por el compilador contienen caracteres ilegales en los identificadores de C#, pero son válidos en el sistema de tipo de marco subyacente.

no tengo Reflector útil en este momento, así que no puedo confirmar, pero si se siente como una mancha de luz masoquismo, reflexionar sobre su montaje y echar un vistazo al código del compilador escribe a dejemos que los meros mortales usen un buen azúcar sintáctico como yield return :) Hay mucha información disponible en la web sobre cómo funciona exactamente.

Editar: después de un poco más la búsqueda, un par de los mejores:
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

+0

Gracias por la respuesta shambulator. Supongo que la respuesta a "¿cómo puedo evitarlo?" Parte de mi pregunta es "no se puede sin cambiar su diseño"? – stusherwin

+0

Miedo, al menos hasta donde puedo ver. – shambulator

3

he tenido problemas similares, y lo que he hecho es modificar la aplicación para construir una lista de elementos y luego regresa la lista.

Eso me ha permitido encontrar el error, corregirlo. Después de corregir el error, cambio la implementación a un retorno de rendimiento.

Doloroso.

4

El método no se ejecuta hasta que enumere en él.

var p = UserValidator.Validate(user).ToList(); 

Ahora puede depurar su código.

+0

Creo que es posible que hayas malentendido la pregunta :) – stusherwin

Cuestiones relacionadas