为什么IEnumerable<T>.Reverse()
会返回带有原始集合的反向集合,而List<T>
会反转原始集合本身?这有点让我感到困惑,因为List<T>
继承自IEnumerable<T>
。
答案 0 :(得分:7)
因为他们有两种不同的方法。
List<T>.Reverse
是List<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的一部分,一个直接在类型上实现。