我对List<T>.Reverse()
和Reverse(this IEnumerable<TSource> source)
有疑问。
查看代码:
// Part 1
List<int> list = new List<int> { 1, 2, 3 };
foreach (int x in list)
Console.Write(x);
Console.WriteLine();
list.Reverse();
foreach (int x in list)
Console.Write(x);
Console.WriteLine();
list.Reverse();
// Part2
IList<int> ilist = list;
foreach (int x in list)
Console.Write(x);
Console.WriteLine();
ilist.Reverse();
foreach (int x in ilist)
Console.Write(x);
Console.WriteLine();
ilist.Reverse();
我的结果:
123
321
123
123
因为Reverse()
- 第1部分是List<T>.Reverse()
,Reverse()
- 第2部分是Reverse(this IEnumerable<TSource> source)
我希望在Part2中为List<int>.Reverse()
执行IList<int>
。我怎么能这样做?
答案 0 :(得分:9)
IList<int>
没有Reverse
方法,因此它使用扩展方法。在List<T>.Reverse
引用中使用IList<int>
的唯一方法是将其转换或转换为List<int>
。只有当你确定它真的是List<int>
时才会投射:
IList<int> abstractList;
var concreteList = (List<int>)abstractList;
concreteList.Reverse();
另一种选择是从List<int>
实例创建 IList<int>
,而不是假设它已经是List<int>
:
IList<int> abstractList;
var concreteList = new List<int>(abstractList);
concreteList.Reverse();
Reverse
扩展方法实际上不影响基础列表的原因是因为它在IEnumerable<T>
上运行,Enumerable
不一定是可写的(没有Reverse
扩展方法会对原始集合进行更改,并返回 new 集合。
要使用此版本的Reverse
,只需使用IList<int> abstractList;
IEnumerable<int> reversedList = abstractList.Reverse();
来电的产品,而不是原始列表:
{{1}}
答案 1 :(得分:4)
在第二个示例中,您正在使用针对IEnumerable<T>
的扩展方法,这不会改变原始集合,而是生成一个查询,该查询将以相反的顺序生成原始列表的序列。也就是说,如果你想利用ilist.Reverse()
的结果,你会说
var reversedList = iList.Reverse();
// reversedList is IEnumerable<int>
// 'list' and 'ilist' are not changed
foreach (int item in reversedList)
Console.Write(item);