为什么IList<> .Reverse()不像List<>()那样工作。

时间:2011-01-12 19:29:59

标签: c# list interface methods ambiguity

我对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>。我怎么能这样做?

2 个答案:

答案 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);