11

我有一个方法,它返回一个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”访问外部类型“Validation.UserValidator.Validate”的非静态成员

有谁知道这是为什么以及我该如何解决?

4

3 回答 3

7

好的,刚刚试了一下,我明白你的意思了。那很痛苦!我怀疑这与编译器执行的幕后工作(创建嵌套类等)有关,以实现yield. 绕过它的一种方法(我最初尝试您的代码的方式)是使Validate方法静态,但显然这对设计不利。

我认为错误消息如此迟钝的原因是以下几种组合:

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

我现在手边没有 Reflector,所以无法确认,但如果你觉得自己有点受虐狂,请反思你的程序集并查看编译器编写的代码,让我们这些凡人使用 nice语法糖,如yield return:) 网上有很多关于它是如何工作的信息。

编辑:经过多一点搜索,一些更好的:http:
//blogs.msdn.com/b/ericlippert/archive/tags/iterators/
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

于 2010-05-28T08:59:03.650 回答
6

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

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

您现在可以调试您的代码。

于 2011-11-14T15:52:17.670 回答
3

我遇到过类似的问题,我所做的是修改实现以建立一个元素列表,然后返回该列表。

这使我能够找到错误并纠正它。纠正错误后,我将实现改回收益回报。

痛苦。

于 2011-09-06T08:55:48.493 回答