使用yield return枚举器方法在Visual Studio中进行调试监视的问题

stu*_*win 11 debugging ienumerable watch yield-return visual-studio-2008

我有一个方法,它返回一个IEnumerable<>使用yield return语法构建的方法:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我在方法中放置断点,我可以跨越每一行,但如果我尝试使用Watch或Immediate窗口来查看变量的值,我会收到此错误:

无法通过嵌套类型"Validation.UserValidator"访问外部类型"Validation.UserValidator.Validate"的非静态成员

有谁知道为什么会这样,我怎么能绕过它?

sha*_*tor 7

好的,试了一下,我明白了你的意思.那太痛苦了!我怀疑它与编译器所做的幕后工作(创建嵌套类等)有关,以实现可恢复的状态机类型逻辑yield.解决它的一种方法(我最初尝试你的代码的方式)是使Validate方法静态,但显然这对设计来说并不好.

我认为错误消息如此迟钝的原因是:

  1. 生成的类在您的源中不存在,因此VS没有用于引用它们的名称.
  2. IIRC,编译器生成的名称包含C#标识符中的非法字符,但在底层Framework类型系统中有效.

我现在没有Reflector方便,所以无法确认,但如果你感觉像一个光受虐狂的地方,反思你的程序集,看看编译器编写的代码,让我们凡人使用不错语法糖就像yield return:)网上有很多关于它是如何工作的信息.

编辑:经过一番搜索后,可以看到几个更好的:
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx


小智 5

在枚举之前,该方法不会运行.

var p = UserValidator.Validate(user).ToList();
Run Code Online (Sandbox Code Playgroud)

您现在可以调试代码.