【发布时间】:2012-10-19 20:33:23
【问题描述】:
我们有一个非常古老的代码库(实际上质量并不差)。它可以追溯到 .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(不是为了这个问题,只是为了一般用途),但它似乎没有涵盖这种类型的场景。
【问题讨论】:
-
为什么不修复用途 - 而不是继续手动调用
GetEnumerator()?我希望它们中的大多数最终都会成为foreach循环,对吧? -
用法是否足够一致,您可以正则表达式或编写快速脚本来读取所有 .cs 文件并查找/替换模式?
-
@JonSkeet 我们很乐意,但我们没有一个月的时间来完成这项任务 :) 所以我们现在的计划是现在解决根本原因,这样我们就可以编写好的新代码,并在我们遇到旧代码时对其进行修复
-
螺丝自动化,找个实习生就行了。
-
@Earlz 您能否拥有两个属性,一个是 IEnumerator(现有的),另一个是名称相似的
IEnumerable<T>。新用途使用新特性,旧用途使用旧特性。当你遇到旧的时重构它的用途,然后尽可能将其完全删除。
标签: c# .net refactoring ienumerable automated-refactoring