Visual Studio 中使用收益返回枚举器方法进行调试监视时出现问题

发布于 2024-09-02 22:59:45 字数 699 浏览 13 评论 0原文

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

如果我在该方法中放置一个断点,我可以跳过每一行,但是如果我尝试使用“监视”或“立即”窗口来查看变量的值,则会收到此错误:

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

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

I have a method which returns an IEnumerable<> which it builds up using the yield return syntax:

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;
        }
    }
}

If I put a breakpoint in the method, I can step over each line, but if I try to use the Watch or Immediate windows to view the value of a variable I get this error:

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

Does anyone know why this is and how I can get around it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝海似她心 2024-09-09 22:59:45

好的,刚刚尝试了一下,我明白你的意思了。太痛苦了!我怀疑这与编译器为实现可恢复状态机类型逻辑而进行的幕后工作(创建嵌套类等)有关。解决这个问题的一种方法(我最初尝试你的代码的方法)是使 Validate 方法静态,尽管显然这对于​​设计来说并不是很好。

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

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

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

编辑:经过更多搜索,有几个更好的:
http:// /blogs.msdn.com/b/ericlippert/archive/tags/iterators/

OK, just tried it out and I see what you mean. That's painful! I suspect it has to do with the behind-the-scenes work the compiler does (creating nested classes and such) to implement the resumable state machine-type logic for yield. One way of getting around it (the way I originally tried your code) is to make the Validate method static, though obviously that's not great for the design.

I think the reason the error message is so obtuse is some combination of:

  1. The generated classes don't exist in your source, so VS has no names by which to refer to them.
  2. IIRC, the names generated by the compiler contain characters illegal in C# identifiers, but valid in the underlying Framework type system.

I don't have Reflector handy right now, so can't confirm, but if you're feeling like a spot of light masochism, reflect on your assembly and take a look at the code the compiler writes to let us mere mortals use nice syntactic sugar like yield return :) There's lots of information available on the web on how exactly it all works.

Edit: after a little more searching, a couple of the better ones:
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

久伴你 2024-09-09 22:59:45

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

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

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

The method isn't run until you enumerate into it.

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

You can now debug your code.

凉城 2024-09-09 22:59:45

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

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

痛苦。

I've had similar problems, and what I have done is to modify the implementation to build up a list of elements, and then return the list.

That has allowed me to find the bug, correct it. After the bug has been corrected, I change the implementation back to a yield return.

Painful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文