从IEnumerable <type> .GetEnumerator()</type> </type>访问IEnumerable <type> .GetEnumerator()

时间:2010-12-19 10:34:38

标签: c# generics interface ienumerable explicit-implementation

请找到代码有错误,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 个答案:

答案 0 :(得分:2)

好吧,既然您明确地实现了两个 GetEnumerator方法,那么您可以这样做:

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

但我有两个问题:

  1. 为什么要明确实现接口?这根本不是惯用语。 (编辑:现在很清楚为什么;这是生成的代码)。
  2. 这段代码甚至是由人写的吗?看起来很像C#编译器为迭代器块生成的内容。如果是这样,你是如何得到它的?反编译器?请注意,反编译器通常会在正确的 IL上跳闸并生成无法编译的C#代码。
  3. 编辑:我看了反编译器的反编译代码的反编译代码(我怀疑这是你正在使用的反编译器?)。它似乎证明了这个错误,即非泛型版本反编译为明显无效:

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

    编辑: 您需要进行编译的其他修复程序似乎是:

    1. MoveNext方法的辅助功能更改为public
    2. 通用 ExpressionParser.方法中删除GetEnumerator的提及。

    3. 您可以在Ideone上尝试。

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

      输出:

      System.String
      System.Object
      

      如果您能够更好地解释真正想要做什么,我们可以更好地帮助您。修复错误反编译的代码并不好玩。例如,如果您需要为类型层次结构编写枚举器,那么使用迭代器块更容易很多,而不会遇到反编译动态LINQ的麻烦。