是否有任何工具可以帮助我们将IEnumerator属性重构为IList <t>或类似的?</t>

时间:2012-10-19 20:33:23

标签: c# .net refactoring ienumerable automated-refactoring

我们有一个非常古老的代码库(实际上并不是非常糟糕的质量)。它可以追溯到.Net发布之前的时间,我怀疑这是一些奇怪的约定的原因。

无论如何,我们刚刚开始放弃.Net 1.1的支持,并且正在将事情转换为泛型并使用Linq和所有有趣的东西。我们代码库中最讨厌的模式之一是我们会有像

这样的东西
private ArrayList mylist;
public IEnumerator MyList
{
  get
  {
    if(mylist==null)
      return new EmptyEnumerator.Enumerator;
    return mylist.GetEnumerator();
  }
}

这种模式特别糟糕,因为它阻止我们简单地执行foreach(var item in MyList)因为IEnumerator没有实现IEnumerable。相反,我们必须做这样的事情:

IEnumerator enumerator=MyList;
while(enumerator.MoveNext())
{
    object item=enumerator.Current;
}

因此,对于重构,我们当然希望使用ReadOnlyCollection<T>IList<T>或类似内容。但要执行此操作,我们必须更新每个对MyList的引用:

IEnumerator enumerator=MyList;

IEnumerator enumerator=MyList.GetEnumerator();

在某些情况下,我们可以对一个属性进行一百多次引用。有没有可以让这更容易的工具?我们最近得到了Resharper(不是针对这个问题,而是仅供一般使用),但它似乎并没有涵盖这种情况。

1 个答案:

答案 0 :(得分:4)

你需要做的是返回一个同时实现IEnumeratorIEnumerable<T>

的类

实际上制作自己的类型实际上并不难:

public class MessedUpIterator<T> : IEnumerable<T>, IEnumerator
{
    private IEnumerable<T> source;
    private IEnumerator enumerator;

    private IEnumerator MyEnumerator
    {
        get
        {
            return enumerator ?? source.GetEnumerator();
        }
    }

    public MessedUpIterator(IEnumerable<T> source)
    {
        this.source = source;
    }
    public IEnumerator<T> GetEnumerator()
    {
        return source.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return source.GetEnumerator();
    }

    object IEnumerator.Current
    {
        get { return MyEnumerator.Current; }
    }

    bool IEnumerator.MoveNext()
    {
        return MyEnumerator.MoveNext();
    }

    void IEnumerator.Reset()
    {
        MyEnumerator.Reset();
    }
}

现在,您可以返回两者的内容,而不是返回 IEnumeratorIEnumerable<T>

请注意,IEnumerator是在IEnumerable<T>隐式实施的情况下明确实施的,因此会鼓励将其用作IEnumerable,同时仍然将其用作IEnumerator < EM>可能

是的,这很难看,但肯定会更糟。