получить доступ к IEnumerable <Type>.GetEnumerator () из IEnumerable <Type>.GetEnumerator () - PullRequest
1 голос
/ 19 декабря 2010

пожалуйста, найдите код ошибки, что метод getenuemrator () не определен в классе

private sealed class SelfAndBaseClasses : IEnumerable<Type>, IEnumerator<Type>, IEnumerable, IEnumerator, IDisposable
{
  private int state;
  private Type current;
  public Type type;
  private int initialThreadId;
  //public Type type;

  [DebuggerHidden]
  public SelfAndBaseClasses(int state)
  {
    this.state = state;
    this.initialThreadId = Thread.CurrentThread.ManagedThreadId;
  }

  private bool MoveNext()
  {
    switch (this.state)
    {
      case 0:
        this.state = -1;
        break;

      case 1:
        this.state = -1;
        this.type = this.type.BaseType;
        break;

      default:
        goto Label_0055;
    }
    if (this.type != null)
    {
      this.current = this.type;
      this.state = 1;
      return true;
    }
  Label_0055:
    return false;
  }

  [DebuggerHidden]
  IEnumerator<Type> IEnumerable<Type>.GetEnumerator()
  {
    ExpressionParser.SelfAndBaseClasses d;
    if ((Thread.CurrentThread.ManagedThreadId == this.initialThreadId) && (this.state == -2))
    {
      this.state = 0;
      d = this;
    }
    else
    {
      d = new ExpressionParser.SelfAndBaseClasses(0);
    }
    d.type = this.type;
    return d;
  }

  [DebuggerHidden]
  IEnumerator IEnumerable.GetEnumerator()
  {
    return this.System.Collections.Generic.IEnumerable<System.Type>.GetEnumerator();
  }

  [DebuggerHidden]
  void IEnumerator.Reset()
  {
    throw new NotSupportedException();
  }

  void IDisposable.Dispose()
  {
  }

  Type IEnumerator<Type>.Current
  {
    [DebuggerHidden]
    get
    {
      return this.current;
    }
  }

  object IEnumerator.Current
  {
    [DebuggerHidden]
    get
    {
      return this.current;
    }
  }
}

1 Ответ

2 голосов
/ 19 декабря 2010

Ну, так как вы реализуете оба GetEnumerator методы явно, вы можете сделать это:

IEnumerator IEnumerable.GetEnumerator()
{
    return ((IEnumerable<Type>)this).GetEnumerator();
}

Но у меня есть два вопроса:

  1. Почему вы хотите явно реализовать оба интерфейсы?Это совсем не идиоматично.(РЕДАКТИРОВАТЬ: теперь понятно, почему; это сгенерированный код).
  2. Этот код даже написан человеком?Подозрительно похоже на то, что компилятор C # генерирует для блоков итераторов.Если да, то как вы к этому попали?Декомпилятор?Обратите внимание, что для декомпиляторов обычно срабатывает правильный IL и создается код C #, который не компилируется.

РЕДАКТИРОВАТЬ: я посмотрел на декомпилированный код дляблок итератора с Reflector (я подозреваю это декомпилятор, который вы используете?).Похоже, он демонстрирует эту ошибку, то есть неуниверсальная версия декомпилируется как явно недействительная:

return this.System.Collections.Generic.IEnumerable<Foo>.GetEnumerator(); 

РЕДАКТИРОВАТЬ: другие исправления, которые вам нужно получить для компиляции, выглядят так:

  1. Измените доступность метода MoveNext на public.
  2. Удалите упоминания ExpressionParser. в методе generic GetEnumerator.

Вы можете попробовать его на Ideone .

foreach (Type t in new SelfAndBaseClasses(0) { type = typeof(string) })
   Console.WriteLine(t);

Выход:

System.String
System.Object

Если вымогли бы лучше объяснить, что вы действительно хотите сделать, мы можем помочь вам лучше.Исправлять некорректно декомпилированный код не весело.Например, если вам нужно написать перечислитель для иерархии типов, то это будет намного проще сделать с блоком итератора, чем пытаться декомпилировать Dynamic LINQ.

...