【问题标题】:Problem with debug watch in Visual Studio with yield return enumerator methods在 Visual Studio 中使用 yield return 枚举器方法进行调试监视的问题
【发布时间】:2011-02-25 00:45:55
【问题描述】:

我有一个返回 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”通过 嵌套类型'Validation.UserValidator'

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 感谢 shambulator 的回复。我想我的问题中“我怎样才能绕过它”部分的答案是“你不能不改变你的设计”?
    • 恐怕是这样,至少在我看来。
    【解决方案2】:

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

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

    痛苦。

    【讨论】:

      【解决方案3】:

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

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

      您现在可以调试代码了。

      【讨论】:

      • 我想你可能误解了这个问题:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多