我们有一个非常老的代码库(实际上并不是很糟糕的质量)。它可以追溯到.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(不是针对此问题,而仅用于一般用途),但是它似乎并未涵盖此类情况。
最佳答案
听起来您需要做的是返回一个同时实现IEnumerator
和IEnumerable<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();
}
}
现在,您无需返回
IEnumerator
或IEnumerable<T>
,而可以返回同时执行这两个操作的东西。请注意,
IEnumerator
是显式实现的,而IEnumerable<T>
是隐式实现的,因此它将鼓励将其用作IEnumerable
,同时仍然可以将其用作IEnumerator
。是的,这很丑陋,但肯定会更糟。
关于c# - 有没有什么工具可以帮助我们将IEnumerator属性重构为IList <T>或类似的东西?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12982047/