IEnumerable<T>.Reverse()
返回反转的集合和原始集合一样,而List<T>
却把原始集合本身反转呢?这对我来说有些困惑,因为List<T>
是从IEnumerable<T>
继承而来。IEnumerable<T>.Reverse()
返回反转的集合和原始集合一样,而List<T>
却把原始集合本身反转呢?这对我来说有些困惑,因为List<T>
是从IEnumerable<T>
继承而来。List<T>.Reverse
是 List<T>
上的实例方法,这会直接修改该列表。
而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"}
。
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();
将您原来的列表反转。希望这样说清楚了。
IEnumerable<T>
的Reverse
是Linq的一部分,是作为扩展方法添加的(Enumerable.Reverse<T>
)。在List<T>
实现Reverse
之后,它被添加了进来。
IEnumerable<T>
也不是对象的集合。它只是告诉消费者如何获取这些项。
List<T>
实现了Reverse
之后添加的”。 - Lucas Trzesniewski这些是不同的方法,要记住。本质上是不同的,除了名称外没有任何共同点。
void List.Reverse
是仅适用于 List 实例的方法,它可以就地反转列表或其中一部分。
IEnumerable Enumerable.Reverse
是一个扩展方法(顺便说一下,IList
也有它!),它创建一个新的可枚举对象并将其顺序反转。
不存在 IEnumerable<T>.Reverse()
这样的东西。它是 Enumerable.Reverse<T>(this IEnumerable<T>)
,是 Linq 的扩展方法,适用于所有的 IEnumerable<>
。
现在我们已经确定它们的来源,很容易理解它们为什么如此不同。Linq 添加了创建“处理流”的方法,通过每次创建新实例来实现。
List<T>.Reverse()
是 List
的一个方法,就像它的所有方法(例如 Add
)一样,直接修改实例。
IEnumerable<T>
有一个底层实现,可以是 List<T>
、Hashtable<T>
或其他实现 IEnumerable 的东西。
List<T>
本身就是实现,所以您可以直接修改该实例。
正如其他人提到的,一个是扩展方法和 Linq 的一部分,另一个是直接在类型上实现的。
IEnumerable<T>
是一个接口,而List<T>
并不继承它,它实现了它。这是一个巨大的区别。 - MarcinJuraszek