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>
)。它是在 Reverse
为 List<T>
实施后添加的。
IEnumerable<T>
也不是对象的集合。它只是告诉消费者如何获得这些物品。
因为它们是两种不同的方法。
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
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();
反转您的原始列表。我希望这是有道理的。
为什么 IEnumerable<T>.Reverse()
returns 与原始集合的反转集合和 List<T>
反转原始集合本身?这让我有些困惑,因为 List<T>
继承自 IEnumerable<T>
.
IEnumerable<T>
上的 Reverse
是 Linq 的一部分,并作为扩展方法添加 (Enumerable.Reverse<T>
)。它是在 Reverse
为 List<T>
实施后添加的。
IEnumerable<T>
也不是对象的集合。它只是告诉消费者如何获得这些物品。
因为它们是两种不同的方法。
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
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();
反转您的原始列表。我希望这是有道理的。