IEnumerable <t> .Reverse&amp;列表<T> .Reverse

时间:2015-05-15 15:23:31

标签: c# generic-collections

为什么IEnumerable<T>.Reverse()会返回带有原始集合的反向集合,而List<T>会反转原始集合本身?这有点让我感到困惑,因为List<T>继承自IEnumerable<T>

6 个答案:

答案 0 :(得分:7)

因为他们有两种不同的方法。

List<T>.ReverseList<T>上的实例方法。这会修改List。

Enumerable.Reverse<T>IEnumerable<T>上的扩展方法。这将创建一个新序列,以相反的顺序枚举源序列。

您可以通过调用静态方法在List<T>上使用后者:

var list = new List<string>{"1","2"};
var reversed = Enumerable.Reverse(list)

或者通过转换为IEnumerable<T>

IEnumerable<string> list = new List<string>{"1","2"};
var reversed = list.Reverse();

在这两种情况下,list保持不变,枚举时reversed返回{"2","1"}

答案 1 :(得分:7)

从概念上讲,这可能是因为当您想要表示不可变的项集合时使用IEnumerable。也就是说,您只想读取列表中的项目,而不是添加/插入/删除或以其他方式更改集合。在此数据视图中,以不同的顺序返回新的IEnumerable是预期的结果。当您使用List时,您希望能够添加/插入/删除或以其他方式改变集合,因此在该上下文中将需要更改原始列表顺序的Reverse方法。

正如其他人所说,IEnumerable是一个界面而List是一个类。 List实施IEnumerable

所以,

 IEnumerable<String> names = new List<String>();
 var reversedNames = names.Reverse();

获得第二个名单,反转。 而,

 List<String> names = new List<String>();
 names.Reverse(); 

撤消原始列表。我希望这是有道理的。

答案 2 :(得分:3)

Reverse上的{p> IEnumerable<T>是Linq的一部分,并作为扩展方法添加(Enumerable.Reverse<T>)。在为Reverse实施List<T>后添加了它。

IEnumerable<T>也不是对象的集合。它只是告诉消费者如何获得这些物品。

答案 3 :(得分:0)

记住这些是不同的方法。本质上是不同的,没有什么常见但只是一个名字。

void List.Reverse是一种仅限List实例的方法,它可以反转列表或部分列表。

IEnumerable Enumerable.Reverse是一种扩展方法(btw IList也有它!)创建一个新的枚举,顺序颠倒。

答案 4 :(得分:0)

没有IEnumerable<T>.Reverse()这是Enumerable.Reverse<T>(this IEnumerable<T>)这样的事情,它的Linq扩展方法适用于所有IEnumerable<>

现在我们已经建立了它们的来源,很容易理解为什么它们如此不同。 Linq添加了创建“处理流”的方法,并且每次都通过创建新实例来实现。

List<T>.Reverse()List的一种方法,并且像所有方法一样(例如Add)直接修改实例。

答案 5 :(得分:0)

IEnumerable<T>有一个底层实现,可以是List<T>Hashtable<T>或其他实现IEnumerable的实现。

List<T>本身的实现,因此您可以直接修改该实例。

正如其他人提到的那样,一个是扩展方法,也是Linq的一部分,一个直接在类型上实现。