IEnumerable<T>.Reverse 和 List<T>.Reverse 之间的区别

difference between IEnumerable<T>.Reverse & List<T>.Reverse

为什么 IEnumerable<T>.Reverse() returns 与原始集合的反转集合和 List<T> 反转原始集合本身?这让我有些困惑,因为 List<T> 继承自 IEnumerable<T>.

IEnumerable<T> 上的

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

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

因为它们是两种不同的方法。

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 returns {"2","1"}.

这些是不同的方法,记住。本质上是不同的,除了名字没有共同之处。

void List.Reverse仅是List实例的一个方法,它会原地反转列表或部分列表。

IEnumerable Enumerable.Reverse 是一种扩展方法(顺便说一句 IList 也有它!)创建一个新的可枚举的顺序相反。

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

既然我们已经确定了它们的来源,就很容易理解为什么它们如此不同了。 Linq增加了创建"processing streams"的方法,它是通过每次创建新实例来实现的。

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

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

List<T>本身的实现,所以你可以直接修改那个实例。

正如其他人所提到的,一种是扩展方法和 Linq 的一部分,一种是直接在类型上实现的。

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

正如其他人所说,IEnumerable 是一个接口,List 是一个 class。 List 实施 IEnumerable.

所以,

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

给你第二个列表,颠倒了。 然而,

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

反转您的原始列表。我希望这是有道理的。