对于List
对象,我们有一个名为方法反向() 。
它扭转列表的顺序“到位”,它不返回任何东西。
对于IEnumerable
对象,我们有一个名为扩展方法反向() 。
它返回另一个IEnumerable的。
我需要以相反的顺序throught列表进行迭代,所以我不能直接使用第二种方法,因为我得到一个列表,我不希望扭转这种局面,只是重复倒退。
所以,我可以这样做:
for(int i = list.Count - 1; i >=0; i--)
要么
foreach(var item in list.AsEnumerable().Reverse())
我发现它比我有一个IEnumerable的可读性,只是做
foreach(var item in list.Reverse())
我不明白为什么这2种方法已经实施这种方式,具有相同的名称。 这是很烦人和混乱。
为什么没有在反向(的地方叫BackwardsIterator())扩展为所有IEnumerable的工作?
我对这个选择的历史原因,比“怎么做”的东西多很感兴趣!
值得注意的是,该清单方法比扩展方法大很多。 命名很可能保持相同的Reverse
似乎比更简洁BackwardsIterator
。
如果你想绕过列表版本,并转到扩展方法,你需要像对待一个列表IEnumerable<T>
var numbers = new List<int>();
numbers.Reverse(); // hits list
(numbers as IEnumerable<int>).Reverse(); // hits extension
或致电扩展方法为静态方法:
Enumerable.Reverse(numbers);
请注意, Enumerable
版本将需要完全重复的基本枚举,以便开始反向迭代它。 如果你打算做在同一个枚举此多次,考虑永久扭转秩序和正常迭代它。
自己写的BackwardsIterator呢!
public static IEnumerable BackwardsIterator(this List lst)
{
for(int i = lst.Count - 1; i >=0; i--)
{
yield return lst[i];
}
}
的存在List<T>.Reverse
长之前的存在IEnumerable<T>.Reverse
。 它们被命名为同样的原因是...无能。 这是一个可怕误事; 明确的LINQ IEnumerable<T>
函数应该被赋予不同的名称...例如, Backwards
......因为它们具有完全不同的语义。 正因为如此,它奠定了程序员一个可怕的陷阱-有人可能的类型更改list
,从List<T>
到,例如, Collection<T>
突然list.Reverse();
的,而不是扭转list
到位,简单地返回一个IEnumerable<T>
被丢弃。 它不能被夸大了它是多么的无能是MS的给这些方法相同的名称。
为了避免您可以定义自己的扩展方法的问题
public static IEnumerable<T> Backwards<T>(this IEnumerable<T> source) => source.Reverse();
您甚至可以添加可转位名单的高效处理的特殊情况:
public static IEnumerable<T> Backwards<T>(this IEnumerable<T> source) =>
source is IList<T> list ? Backwards<T>(list) : source.Reverse();
public static IEnumerable<T> Backwards<T>(this IList<T> list)
{
for (int x = list.Count; --x >= 0;)
yield return list[x];
}
文章来源: Why there is two completely different version of Reverse for List and IEnumerable?