Проблема с отладкой смотрит в Visual Studio с методами перечислителя возврата урожая

У меня есть метод, который возвращается 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 для просмотра значения переменной, я получаю эту ошибку:

Не может получить доступ к нестатическому члену внешнего типа 'Проверка. UserValidator. Проверьте' через вложенный тип 'Проверку. UserValidator'

Кто-либо знает, почему это и как я могу обойти его?

11
задан stusherwin 28 May 2010 в 08:30
поделиться

1 ответ

OK, только что попробовал и понял, что вы имеете в виду. Это больно! Я подозреваю, что это связано с закулисной работой компилятора (создание вложенных классов и тому подобное) для реализации логики возобновляемой машины состояний для yield. Один из способов обойти это (как я первоначально попробовал ваш код) - сделать метод Validate статическим, хотя очевидно, что это не очень хорошо для дизайна.

Я думаю, что причина столь тупого сообщения об ошибке заключается в следующем:

  1. Сгенерированные классы не существуют в вашем исходном коде, поэтому VS не имеет имен, по которым к ним можно обратиться.
  2. IIRC, имена, сгенерированные компилятором, содержат символы, недопустимые в идентификаторах C#, но допустимые в базовой системе типов Framework.

У меня сейчас нет под рукой Reflector, так что не могу подтвердить, но если вам захочется легкого мазохизма, поразмышляйте над своей сборкой и посмотрите на код, который компилятор пишет, чтобы позволить нам, простым смертным, использовать приятный синтаксический сахар вроде yield return :) В сети есть много информации о том, как именно это все работает.

Edit: после небольшого поиска, пара лучших:
http://blogs.msdn.com/b/ericlippert/archive/tags/iterators/
http://csharpindepth.com/Articles/Chapter6/IteratorBlockImplementation.aspx

7
ответ дан 3 December 2019 в 08:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: