1

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

1 に答える 1

3

両方のメソッドを明示的に実装しているので、次のGetEnumeratorようにすることができます。

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

しかし、2 つの質問があります。

  1. なぜ両方のインターフェースを明示的に実装したいのですか? それはまったく慣用的ではありません。(編集:理由は明らかです。これは生成されたコードです)。
  2. このコードは人間によって書かれていますか? C# コンパイラがイテレータ ブロックに対して生成するものと疑わしいほど似ています。もしそうなら、どうやってそれを手に入れましたか?逆コンパイラ?逆コンパイラが正しいIL でつまずいて、コンパイルされない C# コードを生成することはよくあることに注意してください。

編集: Reflector を使用した反復子ブロックの逆コンパイルされたコードを調べました (これは、使用している逆コンパイラであると思われます)。このバグを示しているように見えます。つまり、非ジェネリック バージョンは明らかに無効なものとして逆コンパイルされます。

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

編集:これをコンパイルするために必要な他の修正は次のようです:

  1. MoveNextメソッドのアクセシビリティを に変更しますpublic
  2. ジェネリックメソッドExpressionParser.内の言及を削除します。 GetEnumerator

Ideoneで試すことができます。

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

出力:

System.String
System.Object

あなたが本当にやりたいことをよりよく説明できれば、私たちはあなたをより良く助けることができます. 間違って逆コンパイルされたコードを修正するのは楽しいことではありません。たとえば、型階層の列挙子を記述する必要がある場合、Dynamic LINQ を逆コンパイルする手間をかけずに、反復子ブロックを使用する方がはるかに簡単です。

于 2010-12-19T10:45:24.563 に答える