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

时间:2010-05-28 08:14:56

标签: visual-studio-2008 debugging ienumerable watch yield-return

我有一个返回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;
        }
    }
}

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

  

无法访问非静态成员   外部类型'Validation.UserValidator.Validate'via   嵌套类型'Validation.UserValidator'

有谁知道为什么会这样,以及如何绕过它?

3 个答案:

答案 0 :(得分:7)

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

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

的某种组合
  1. 生成的类在您的源中不存在,因此VS没有可用于引用它们的名称。
  2. IIRC,编译器生成的名称包含C#标识符中的非法字符,但在底层Framework类型系统中有效。
  3. 我现在没有Reflector方便,所以无法确认,但是如果你感觉像一个光受虐狂的地方,反思你的程序集并看看编译器写的代码让我们单纯凡人使用像yield return这样好的语法糖:)网上有很多关于它究竟是如何运作的信息。

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

答案 1 :(得分:5)

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

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

您现在可以调试代码。

答案 2 :(得分:3)

我遇到了类似的问题,我所做的是修改实现以构建元素列表,然后返回列表。

这让我找到了错误,纠正了它。错误更正后,我将实现更改回收益率返回。

痛。

相关问题